5
  • Given an object already created, what is the best way to figure out how it was created? Basically, I would like to figure out the actual parameters during the object creation (eventually the actual parameters passed to the class init method).

  • Note that I mean the actual parameters here, not the formal parameters. The formal parameters may perhaps accept 20 different parameters, maybe 16 of them are optional with default values each. In the actual call (i.e. creating the object instance), perhaps only 5 parameters are given, and 3 of them happens to be the same as default value.

  • What I would like to do is to retrieve these 5 parameters and their values, after the object has been created.

  • For code example, lets say the class of interest is called Kmodel. Kmodel constructor accepts 20 different parameters (16 of them don't need to be specified by caller).

  • In caller's code, this would be something like: kmodel = Kmodel( param1 = 10, param2 = None, param3 = "name3", param4 = [1, 3, 5], param5 = dict("keyx": "valuey"}) ...

  • Later call a method to find out the actual parameters calling Kmodel( )
    figure_out_actual_params(kmodel)

  • Now the implementation of the code to figure out: def figure_out_acutal_params( kmodel ): ...

  • here is the code that needs to be implemented to reconstruct the actual parameters calling Kmodel creation

  • I have examined the inspect module. While inspect can dump out a lot of info, it is not clear to me how to find out the actual param was supplied during the actual creation of the object kmodel.

Thanks!

PS. Note that there are several similar questions on this topic and I have read them all. I don;t think this question is the same. For my question, I can query all the internal object attributes of an object, and I still won't be able to tell which one has been specified during the actual object construction. (The sticky issue is the actual parameter may happen to be the default value.)

HAltos
  • 701
  • 7
  • 6
  • Possible duplicate of [Get all object attributes in Python?](https://stackoverflow.com/questions/6886493/get-all-object-attributes-in-python) – G. Anderson Feb 11 '19 at 23:35
  • That's not possible in general. – mkrieger1 Feb 11 '19 at 23:37
  • Possible duplicate of Get all object attributes in Python? I don't think is the same. I can query all the internal object attributes of an object, and I still won;t be able to tell which one has been specified during the actual object construction. I have looked up several posts in this area and cannot find my answer. – HAltos Feb 11 '19 at 23:41

1 Answers1

1

You can add a section to the __init__ section that saves the input variables perhaps?

class MyThing:
    def __init__(self, arg1, arg2):
        self.arg1 = arg1
        self.arg2 = arg2
        self.initial_settings = [arg1, arg2]

Then as long as you never overwrite self.initial_settings it will hold the values it was initialized with (leaving you free to change self.arg1 for instance). You can also include some if logic to determine if a default parameter was overwritten upon creation (although I don't believe there is a way to tell if an initial value was supplied that equated to the default value). Otherwise I think you will have to use dir(some_object_instance) to determine current attributes, but I don't think there is any other way to determine initial attributes besides storing them during initialization...

Reedinationer
  • 5,661
  • 1
  • 12
  • 33
  • Unfortunately, I am not the author of the object class Kmodel. I don;t control the source code and thus cannot edit/add code. In fact, I don;t even want to make change to the original class code, as my goal is to figure out the constructor info of dozens of different classes... – HAltos Feb 11 '19 at 23:47
  • Yes, I can use dirs and various inspect methods to find out all attributes values of the objects, and compare with the default values. Then I can pull out the non-default values. So that would be the fall back position if mkrieger1 comments holds... – HAltos Feb 11 '19 at 23:51
  • In that case if it were me I would just grab all the values with `dir(some_object)` immediately after you make it and store them for comparison later. This will not let you determine if a default value was supplied explicitly though, which I think is what your question is about. I'm not sure why you would want to do this anyways, but I think being able to compare them to initial values is a good start! – Reedinationer Feb 12 '19 at 00:01
  • You could subclass it however, define a **def __init__(*args, **kwds)**, save ‘locals()’ and call **super(yourclass).__init__(*args, **kwds)**. If you don't control the creates you’d have harder time and monkeypatching might be needed. – JL Peyret Feb 12 '19 at 00:44
  • You mean subclass from the original class? Hmm... there are literally dozens or perhaps even hundreds of classes that this routine figure_out_acutal_param( ) needs to deal with, so that means I need to subclass from each of them? (I have an earlier prototype that defines one method for all classes. This method is with signature (*args, **kargs) similar to yours. The caller simply pass in any constructor. Then this method will use inspect to figure out the actual parameter and save it somewhere. I think this perhaps is similar to what you have in mind, without getting to subclass. – HAltos Feb 12 '19 at 01:58
  • Using import inspect; inspect.getcallargs(kmodel.__init__) seems to be the way. The function returns all other optional parameters with their defaults. However, if say, one param is required to the constructor, one has to do getcallargs(kmodel.__init__, arg1) where arg1 has to be of compatible type. (Of course, one still cannot get the actual parameters, just like what mkrieger1 said. – HAltos Feb 12 '19 at 22:12
  • @HAltos If you've solved your problem, why not post the solution as an answer and accept your own answer then? – Reedinationer Feb 12 '19 at 23:17
  • Good idea. I have done some testing and I think the approach using inspection would work, and be able to figure out the non-default value used in the constructor. My solution is not done yet (I was pulled off to attend some other fire). Let me work out the code and post in due course. Thanks! – HAltos Feb 14 '19 at 20:05