简体   繁体   中英

Access to __init__ arguments

Is is possible to access the arguments which were passed to __init__ , without explicitly having to store them?

eg

class thing(object):
  def __init__(self, name, data):
    pass # do something useful here

t = thing('test', [1,2,3,])
print t.__args__ # doesn't exist

>> ('test', [1,2,3])

The use-case for this is creating a super-class which can automatically store the arguments used to create an instance of a class derived from it, without having to pass all the arguments explicitly to the super's __init__ . Maybe there's an easier way to do it!

No, you have to store them. Otherwise they are gone after __init__() returns, as all local variables.

If you don't want to pass all arguments on explicitly, you can use **kwargs :

class Base(object):
    def __init__(self, name, data):
        # store name and data

class Derived(Base):
    def __init__(self, **kwargs):
        Base.__init__(self, **kwargs)

Derived(name="Peter", data=42)

This is not entirely recommended, but here is a wrapper that automatically stores parameter variables:

from functools import wraps
def init_wrapper(f):
    @wraps(f)
    def wrapper(self, *args, **kwargs):
        func_parameters = f.func_code.co_varnames[1:f.func_code.co_argcount]

        #deal with default args
        diff = len(func_parameters) - len(args)
        if diff > 0:
            args += f.func_defaults[-diff:]

        #set instance variables
        for pos, arg in enumerate(func_parameters):
            print pos, arg
            setattr(self, arg, args[pos])

        f(self, *args, **kwargs) #not necessary to use return on __init__()
    return wrapper

Usage:

class A(object):
    @init_wrapper
    def __init__(self, a, b, c):
        print a + b + c

Example:

>>> a = A(1, 2, 3)
6
>>> a.a
1
>>> a.b
2
>>> a.c
3

In a word: No.

What you could do is:

def __init__(self, *args, **kwargs):
    self.args = args
    self.kwargs = kwargs

If you find yourself needing to do this a lot, you could also use a decorator to abstract the task.

I think that you are looking for arbitrary argument lists and keyword arguments combined with super.__init__ .

Give "Python's Super is nifty, but you can't use it" a read before you start down this path though.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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