我应该使用元类,课程装饰器还是覆盖__new__方法?
-
21-09-2019 - |
题
这是我的问题。我希望以下课程具有一堆属性属性。我可以把它们全部写出来 foo
和 bar
, ,或基于我见过的其他一些示例,看起来我可以使用类装饰器,元素或覆盖 __new__
自动设置属性的方法。我只是不确定“正确”的方法是什么。
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')
解决方案
魔术是不好的。它使您的代码更难理解和维护。您几乎不需要元类或 __new__
.
看来您的用例可以用非常简单的代码实现(只有一小段魔术):
class Test(object):
def calculate_attr(self, attr):
return something
def __getattr__(self, name):
return self.calculate_attr(name)
其他提示
A metaclass's __new__
does not become the __new__
for the class you make—it's used to make the class itself. The actual class object is returned by the metaclass. A new instance of a class is returned by __new__
.
Consider the following (insane) code:
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
(I used a function instead of a class as the metaclass. Any callable can be used as a metaclass, but many people choose to right theirs as classes that inherit from type
with new overrided. The differences between that an a function are subtle.)
It outputs
name C
bases ('hello', 'world')
dict {'baz': <function baz at 0x4034c844>, '__module__': '__main__', 'foo': 'bar', '__metaclass__': <function MyMetaClass at 0x40345c34>}
C 7
Does that help you better make sense of what metaclasses are?
You will very seldom need to define a metaclass of your own.
当创建新类 - 非实例 - 时,使用元类。这样,您可以例如注册类(Django做到这一点,并使用它例如在数据库中创建表)。自从 class
是您可以将其视为课堂装饰的指令。