0

I am trying to set the attribute values of a certain class AuxiliaryClass than is instantiated in a method from MainClass class in the most efficient way possible.

AuxiliaryClass is instantiated within a method of MainClass - see below. However, AuxiliaryClass has many different attributes and I need to set the value of those attributes once the class has been instantiated - see the last 3 lines of my code.

Note: due to design constraints I cannot explain here, my classes only contain methods, meaning that I need to declare attributes as methods (see below).

class AuxiliaryClass(object):

    def FirstMethod(self):
        return None
    ...
    def NthMethod(self):
        return None


class MainClass(object):

    def Auxiliary(self):
        return AuxiliaryClass()


def main():
    obj = MainClass()
    obj.Auxiliary().FirstMethod = #some_value
    ...
    obj.Auxiliary().NthMethod = #some_other_value
    # ~~> further code

Basically I want to replace these last 3 lines of code with something neater, more elegant and more efficient. I know I could use a dictionary if I was instantiating AuxiliaryClass directly:

d = {'FirstMethod' : some_value,
     ...
     'NthMethod'   : some_other_value}

obj = AuxiliaryClass(**d)

But this does not seem to work for the structure of my problem. Finally, I need to set the values of AuxiliaryClass's attributes once MainClass has been instantiated (so I can't set the attribute's values within method Auxiliary).

Is there a better way to do this than obj.Auxiliary().IthMethod = some_value?


EDIT

A couple of people have said that the following lines:

    obj.Auxiliary().FirstMethod = #some_value
    ...
    obj.Auxiliary().NthMethod = #some_other_value

will have no effect because they will immediately get garbage collected. I do not really understand what this means, but if I execute the following lines (after the lines above):

    print(obj.Auxiliary().FirstMethod())
    ...
    print(obj.Auxiliary().NthMethod())

I am getting the values I entered previously.

12
  • It looks like MainClass is a class factory. Have you looked at meta classes. Search Google for examples. Here are a few from Jake VanderPlus, Eli Bendersky and Ionel. I'll try to make a quick example in minute. Commented Feb 27, 2017 at 17:15
  • 1
    Wouldn't obj.Auxiliary().FirstMethod = #some_value basically do nothing at all, as soon as that line ends? obj.Auxiliary() returns a new AuxiliaryClass instance, which you modify an attribute of... And then that instance almost immediately gets garbage collected because its refcount drops to zero. Note that reassigning an instance's attribute will have no effect on any other instance of that class, and no effect on the class itself. Commented Feb 27, 2017 at 17:18
  • 1
    Two other suggestions: (1) consider using the property decorator for your methods so they appear as attributes, that way you won't need to use () to "call" them and (2) instead of using a meta class this might also be an example of inheritance, if the auxiliary class can inherit from the main class, this may solve your dilemna. Commented Feb 27, 2017 at 17:21
  • Actually maybe you just want to monkey patch AuxiliaryClass Commented Feb 27, 2017 at 17:24
  • @Kevin Doesn't seem so. An instance i of AuxiliaryClass is encapsulated within the instance of MainClass so I can simply set the attributes of i as I wish. Anyway, when I run the code what you are describing does not seem to be happening. Commented Feb 27, 2017 at 17:25

2 Answers 2

2

To speed things up, and make the customization somewhat cleaner, you can cache the results of the AuxilliaryClass constructor/singleton/accessor, and loop over a dict calling setattr().

Try something like this:

init_values = {
    'FirstMethod' : some_value,
     :
    'NthMethod'   : some_other_value,
}

def main():
    obj = MainClass()
    aux = obj.Auxiliary() # cache the call, only make it once

    for attr,value in init_values.items():  # python3 here, iteritems() in P2
        setattr(aux, attr, value)

    # other stuff below this point
Sign up to request clarification or add additional context in comments.

3 Comments

good idea (see setter in my answer), why not embed this as a method inside the MainClass.Auxiliary method? then just aux = obj.Auxiliary(**d) like the OP wanted?
OP said he can't do that. ("so I can't set the attribute's values within method Auxiliary")
also, the way the OP has FirstMethod and others defined as methods, using setattr will just overwrite them and they wont be "callable" anymore unless some_value is itself a method definition with the same signature as the original FirstMethod.
0

I understand what is happening here: my code has a series of decorators before all methods which allow memoization. I do not know exactly how they work but when used the problem described above - namely, that lines of type obj.Auxiliary().IthMethod = some_value get immediately garbage collected - does not occur.

Unfortunately I cannot give further details regarding these decorators as 1) I do not understand them very well and 2) I cannot transmit this information outside my company. I think under this circumstances it is difficult to answer my question because I cannot fully disclose all the necessary details.

1 Comment

this is not an answer - you should probably put this as an edit or update to your question - expand on what you already put in the section you called "EDIT"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.