Should I use metaclass, class decorator or override __new__ method?

Here is my problem. I want the next class to have a bunch of property attributes. I could write it like fooand bar, or based on some other examples that I've seen, it looks like I could use a decorator class metaclass or override the method __new__to set properties automatically. I'm just not sure what the “right” way to do this would be.

class Test(object):
    def calculate_attr(self, attr):
        # do calculaty stuff
        return attr

    @property
    def foo(self):
        return self.calculate_attr('foo')

    @property
    def bar(self):
        return self.calculate_attr('bar')
+5
source share
3 answers

The magic is bad. This makes your code harder to understand and maintain. You hardly need metaclasses or __new__.

, ( ):

class Test(object):
    def calculate_attr(self, attr):
        return something

    def __getattr__(self, name):
        return self.calculate_attr(name)
+4

__new__ __new__ , , - . . __new__.

() :

def MyMetaClass(name, bases, dict):
    print "name", name
    print "bases", bases
    print "dict", dict
    return 7

class C('hello', 'world'):
    __metaclass__ = MyMetaClass

    foo = "bar"

    def baz(self, qux):
        pass

print "C", C

( ). , , type . : a .)

name C
bases ('hello', 'world')
dict {'baz': <function baz at 0x4034c844>, '__module__': '__main__', 'foo': 'bar', '__metaclass__': <function MyMetaClass at 0x40345c34>}
C 7

, ?

.

+2

Metaclass is used when a new class is created - not an instance. This way you can, for example, register classes (django does this and uses it, for example, to create tables in a database). Because class- this is an instruction that you can consider as a decorator for the class.

+1
source

All Articles