简体   繁体   English

python将args从__new__传递到__init__

[英]python transfer args from __new__ to __init__

i am trying to change the args before i run the init but it doesn't change and stays as the first args that given in the main, how do i change the args from the new ? 我试图在运行init之前更改args,但它没有改变,仍然保持为主程序中给出的第一个args,如何从新的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)

output: 输出:

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'>

It's the metaclass's __call__() method that both calls YourClass.__new__() and YourClass.__init__() , each time passing the arguments it received. 每次传递接收到的参数时,都是元类的__call__()方法都调用YourClass.__new__()YourClass.__init__() So if you want to change the arguments before they reach YourClass.__init__() you have two solutions: decorating __init__() or using a custom metaclass overridding type.__call__() . 因此,如果要在到达YourClass.__init__()之前更改参数,则有两种解决方案:装饰__init__()或使用自定义的元类重写type.__call__()

The (Q&D) decorator version: (Q&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)

The (Q&D) metaclass version (py 2.7.x): (Q&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)

But as Rawing rightously mentions in a comment, you could just do this directly in your class __init__ method . 但是正如Rawing在评论中正确提到的那样, 您可以直接在类__init__方法中执行此操作

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM