3

I found this question while i searched the usage of metaclass in python.It's a good question with a wonderful answer,See Here.But while i followed the example like this:

class UpperAttrMetaclass(type): 

    def __new__(cls, name, bases, dct):

        attrs = ((name, value) for name, value in dct.items() if not name.startswith('__'))
        uppercase_attr = dict((name.upper(), value) for name, value in attrs)

        return type.__new__(cls, name, bases, uppercase_attr)
class Foo(object):
    __metaclass__=UpperAttrMetaclass
    bar = 'bip'

Then:

print(hasattr(Foo,'bar'))

I was hoping it would output False,but instead it was True It seems the metaclass didn't change anything at all. I must have made a mistake.Glad if you can point it out to me!

EDIT: I was using IDLE 3.2,to make my situation more clear.

EDIT: Thanks for all the answers.And i found a good post on this.So i post it hereMetaclass in python 2&3

Community
  • 1
  • 1
Gnijuohz
  • 3,294
  • 6
  • 32
  • 47

2 Answers2

5

You made no mistake. print(hasattr(Foo,'bar')) and print dir(Foo) give me:

False
['BAR', '__class__', ...

What's your Python version? Mine is 2.7.2

If you use Python 3.x, try removing the __metaclass__ attribute and declaring your class as

class Foo(object, metaclass=UpperAttrMetaclass):
    ...
Irfy
  • 9,323
  • 1
  • 45
  • 67
3

As for @Irfy answer - in Python 3 the way to set a metaclass is to pass it as if it where a named-parameter in the class declaration - in your case, the code should be:

class UpperAttrMetaclass(type): 

    def __new__(cls, name, bases, dct):

        attrs = ((name, value) for name, value in dct.items() if not name.startswith('__'))
        uppercase_attr = dict((name.upper(), value) for name, value in attrs)

        return type.__new__(cls, name, bases, uppercase_attr)

class Foo(metaclass=UpperAttrMetaclass):
    bar = 'bip'

(In Python 3, there is no need to inherit from object as well)

Also, just use "dir" to check the class attributes, as in dir(Foo) . No need to be inspecting attribute by attribute with "hasattr" when you can see them all.

jsbueno
  • 99,910
  • 10
  • 151
  • 209
  • You mean when having a metaclass,you don't need to inherit from object? – Gnijuohz Feb 13 '12 at 03:11
  • In Python 3, all classes inherit from `object`, so there's no need to do so explicitly (there are no "old-style" classes). – kindall Feb 13 '12 at 03:22
  • 1
    As Kindall puts it - in Python 3, there is no need to inherit from object. But, yes, in Python 2, if you have a metaclass, you don't need to inherit from object either. (What inheriting from object actually does is setting your metaclass to `type`) – jsbueno Feb 13 '12 at 03:46