我们如何在仍然使用 `class` 关键字的同时覆盖构造函数? [复制]
Posted
技术标签:
【中文标题】我们如何在仍然使用 `class` 关键字的同时覆盖构造函数? [复制]【英文标题】:How can we override the constructor while still using the `class` keyword? [duplicate] 【发布时间】:2020-02-23 00:44:30 【问题描述】:创建类的两种值得注意的方法如下所示:
class Klass:
pass
Klass = type("Klass", tuple(), dict())
我想覆盖构造函数 (__call__
),同时仍然使用 class
关键字,而不是做其他事情,比如直接调用 type
。我真的很想覆盖 (__call__
),而不是 __init__
我的失败尝试如下所示:
尝试 1
class Foo:
@classmethod
def __call__(*args):
print("arr har")
return super(type(args[0]), args[0]).__call__(*args)
instance = Foo()
# did not print "arr har"
尝试 2
class BarMeta(type):
def __call__(*args):
print("hello world")
return super(type(args[0]), args[0]).__call__(*args[1:])
尝试 2A
class Bar:
__metaclass__ = BarMeta
instance = Bar()
# did not print "hello world"
尝试 2B
Baz = BarMeta("Baz", tuple(), dict())
instance = Baz()
# Did print "hello world," but we weren't able to use the `class` keyword to create `Baz`
【问题讨论】:
但是__call__
不是他的构造函数,__new__
是。如果你想覆盖__call__
,你所要做的就是覆盖__call__
如果您使用的是 python 2,尝试 2A 将起作用。在 python 3 中,定义元类的语法是 class Bar(metaclass=BarMeta):
。
@DeepSpace 但是__call__
调用__new__
,而不是相反。 instance = Klass()
与 instance = Klass.__call__()
或 instance = type(Klass).__call__(Klass)
相同
另外,我(显然至少还有另外两个人)很难理解您的问题。最好先明确说明您想要做什么,即“我希望 Bar()
打印 'arr har'”。
@DeepSpace type.__call__
确实是唯一的例子。 repl.it/repls/EvenSandyPress
【参考方案1】:
所有功劳归于Aran-Fey,他将答案作为评论而不是作为答案发布:
class BarMeta(type):
def __call__(*args):
print("hello world")
return super(type(args[0]), args[0]).__call__(*args[1:])
class Bar(metaclass=BarMeta):
pass
instance = Bar()
【讨论】:
以上是关于我们如何在仍然使用 `class` 关键字的同时覆盖构造函数? [复制]的主要内容,如果未能解决你的问题,请参考以下文章