我试图在运行init之前更改args但它没有改变并保持为主要给出的第一个args,我如何更改 new 中的args?
class A(object):
def __init__(self,ip,st):
print 'A arrived to init '+st
self.ip=ip
def __new__(cls,ip,st):
print "A arrived to new"
if ip>10:
return object.__new__(cls,ip,"A")
while True:
s=input("input?")
a=A(s,"a")
print type(a)
输出:
input?88
A arrived to new
A arrived to init a
<class '__main__.A'>
input?44
A arrived to new
A arrived to init a
<class '__main__.A'>
input?22
A arrived to new
A arrived to init a
<class '__main__.A'>
input?12
A arrived to new
A arrived to init a
<class '__main__.A'>
答案 0 :(得分:0)
这是元类的__call__()
方法,每次调用它都会调用YourClass.__new__()
和YourClass.__init__()
。因此,如果您希望在参数到达YourClass.__init__()
之前更改它们,您有两个解决方案:装饰__init__()
或使用自定义元类覆盖type.__call__()
。
(Q&amp; D)装饰者版本:
def changeargs(func):
# fixme : make this a well-behaved decorator
def wrapper(self, *args, **kw):
print("changearg.wrapper(%s, %s)" % (args, kw))
args = (1, 2)
kw = {"hacked": True}
return func(self, *args, **kw)
return wrapper
class Bar(object):
@changeargs
def __init__(self, *args, **kw):
self.args = args
self.kw = kw
def __repr__(self):
return "<Bar(%s, %s)>" % (self.args, self.kw)
(Q&amp; D)元类版本(py 2.7.x):
class FooType(type):
def __call__(self, *args, **kw):
print("FooType.__call__(%s, %s)" % (args, kw))
args = (1, 2)
kw = {"hacked": True}
# fixme : make this collaborative super() call
return type.__call__(self, *args, **kw)
class Foo(object):
__metaclass__ = FooType
def __init__(self, *args, **kw):
self.args = args
self.kw = kw
def __repr__(self):
return "<Foo(%s, %s)>" % (self.args, self.kw)
但正如Rawing在评论中正确提到的那样,你可以直接在你的班级__init__
方法中直接这样做。