我应该使用元类、类装饰器还是重写 __new__ 方法?
这是我的问题。我希望下面的类有一堆属性。我可以像 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')
Here is my problem. I want the following class to have a bunch of property attributes. I could either write them all out like foo
and bar
, or based on some other examples I've seen, it looks like I could use a class decorator, a metaclass, or override the __new__
method to set the properties automagically. I'm just not sure what the "right" way to do it 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')
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
魔法很糟糕。它使您的代码更难理解和维护。您几乎永远不需要元类或 __new__ 。
看起来您的用例可以使用非常简单的代码来实现(只有一点点魔法):
Magic is bad. It makes your code harder to understand and maintain. You virtually never need metaclasses or
__new__
.It looks like your use case could be implemented with pretty straightforward code (with only a small hint of magic):
元类的
__new__
不会成为您创建的类的__new__
— 它用于创建类本身。 实际的类对象由元类返回。类的新实例由 __new__ 返回。考虑以下(疯狂的)代码:(
我使用函数而不是类作为元类。任何可调用的都可以用作元类,但许多人选择将其正确为从
type
继承的类与 new 覆盖的函数之间的差异是微妙的。)它的输出
是否可以帮助您更好地理解元类是什么?
您很少需要定义自己的元类。
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:
(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
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
是一条指令,您可以将其视为类的装饰器。Metaclass is used when new class - not instance - is created. This way you can for example register classes (django does it and uses it for example to create tables in the database). Since
class
is an instruction you can think about as a decorator for a class.