0

Is there a way to get an object's init argument values in python 2.7? I'm able to get the defaults through getargspec but i would like to access passed in values

import inspect

class AnObject(object):
    def __init__(self, kw='', *args, **kwargs):
        print 'Hello'

anobj = AnObject(kw='a keyword arg')
print inspect.getargspec(anobj.__init__)

Returns

Hello
ArgSpec(args=['self', 'kw'], varargs='args', keywords='kwargs', defaults=('',))
ivan_pozdeev
  • 33,874
  • 19
  • 107
  • 152
Mike
  • 65
  • 8
  • 1
    No, that information isn’t kept around anywhere. Most classes will of course store their init arguments in attributes, or use them in some way to build whatever values they do store in attributes, but otherwise, the information is gone, just like the parameters (and other local variables) from _any_ function are gone once the function completes. – abarnert Aug 29 '18 at 18:38
  • 1
    Depending on what you’re actually trying to do here, the answer is probably either “run the code in the debugger” or “modify AnObject (maybe just temporarily) to explicitly store whatever you want to loop up later”. (There’s nothing stopping you from storing `kw, args, kwargs` in an attribute, or `inspect.signature(type(self)).bind(kw, *args, **kwargs)`, or `locals()`, or even the current frame object, but most of those will usually be a bad idea.) – abarnert Aug 29 '18 at 18:42
  • @abarnert Thanks, I was curious if it was possible since I did not wish to modify the class containing the object. – Mike Aug 30 '18 at 15:13

2 Answers2

2

__init__ is treated no differently than any other function. So, like with any other function, its arguments are discarded once it returns -- unless you save them somewhere before that.

The standard approach is to save what you need later in attributes of the instance:

class Foo:
    def __init__(self, a, b, *args, **kwargs):
        self.a = a
        self.b = b
        <etc>

"Dataclasses" introduced in 3.7 streamline this process but require data annotations:

import dataclasses

@dataclasses.dataclass
class Foo:
    a: int
    b: str

is equivalent to:

class Foo:
    def __init__(self, a:int, b:str):
        self.a = a
        self.b = b

Though see Python decorator to automatically define __init__ variables why this streamlining is not very useful in practice.

ivan_pozdeev
  • 33,874
  • 19
  • 107
  • 152
  • 1
    It’s very useful in practice, as long as your class is the kind of class you’d think of given the name “dataclass”, something that’s mainly about keeping a bunch of related values together, like a C pod struct, and then maybe adding behavior on top. It’s not useful for other things like parsers or active simulation objects or whatever, but data classes do some up often enough for people to misuse namedtuple, for attrs to become one of the top projects on PyPI, etc., which is why dataclass was finally added to the language. – abarnert Aug 30 '18 at 16:18
1

You can store them as attributes.

class AnObject(object):
    def __init__(self, kw='', *args, **kwargs):
        self.kw = kw
        self.args = args
        self.kwargs = kwargs 

then just print them:

anobj = AnObject(kw='a keyword arg')
print anobj.kw
print anobj.args
print anobj.kwargs

if you want to see them all, you could take a look into its __dict__ attribute.

cap
  • 365
  • 2
  • 14