这是我的问题。我希望以下类具有一堆属性属性。我可以像foo
和bar
一样写出来,或者基于我见过的其他一些例子,看起来我可以使用类装饰器,元类或覆盖{{1方法自动设置属性。我只是不确定“正确”的做法是什么。
__new__
答案 0 :(得分:5)
魔术很糟糕。它使您的代码更难理解和维护。您几乎不需要元类或__new__
。
看起来你的用例可以用相当简单的代码实现(只有一点点魔力):
class Test(object):
def calculate_attr(self, attr):
return something
def __getattr__(self, name):
return self.calculate_attr(name)
答案 1 :(得分:2)
元类的__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
的类并使用新的覆盖。一个函数是微妙的。)
输出
name C
bases ('hello', 'world')
dict {'baz': <function baz at 0x4034c844>, '__module__': '__main__', 'foo': 'bar', '__metaclass__': <function MyMetaClass at 0x40345c34>}
C 7
这有助于您更好地理解 的元类吗?
你很少需要定义自己的元类。
答案 2 :(得分:1)
创建新类 - 而非实例 - 时使用元类。这样你就可以注册类(django会这样做,并使用它来例如在数据库中创建表)。由于class
是一个指令,你可以将其视为一个类的装饰器。