Parsee
Parsee

Reputation: 71

Initializing a class that consist of many classes in such a way that one of the classes has different attributes

Here are the classes and their relations:

https://i.sstatic.net/6AdA7.png

Code for clarification:

class A(object):
    def __init__(self):
        self.atr = 1

class B(object):
    def __init__(self):
        self.atr = A()

class C(object):
    def __init__(self):
        self.atr = A()


class D(object):
    def __init__(self):
        self.atr1 = B()
        self.atr2 = C()


test1 = D()

Now what do I do if I want to initialize D in such a way that A's self.atr = 2, and that change reflects to all those classes (B and C) that use A as well when I initialize D

Like I imagine it in pseudo code:

test2 = D(A.self.atr = 2)

So you initialize D in such a manner that A's self.atr = 2

Upvotes: 0

Views: 122

Answers (1)

jsbueno
jsbueno

Reputation: 110301

If you want B and C to have different properties, as required by a call from D, the way to do that is to pass parameters for the initialization of B and C so that they know what to do.

The parameter can be itself an instance of A, where the attributes you care for are set before inistantiatin B and C:

class A(object):
    def __init__(self, atr=1):
        self.atr = atr

class B(object):
    def __init__(self, config):
        self.atr = config

class C(object):
    def __init__(self, config):
        self.atr = config

class D(object):
    def __init__(self):
        my_a = A(2)
        self.atr1 = B(my_a)
        self.atr2 = C(my_a)

test1 = D()

update I see from the comments above you seem to dislike this approach duew to the impression you'd have a lot of repetitive code everywhere - That is not the case however - if for example, you have a lot of classes that have to be "preconfigured" like class A, passed to a lot of other classes, you could just create a bundle of all classes pre-configured - you'd still pass on a single parameter to each instance you create.

Also, there are, as you want, mechanisms in Python to allow dynamically reconfiguring classes - using "variables" being one of them - the probelm is that doing it in this naive way you want, you'd ahve pretty soon an unmaintainable mess.

For example, if you just use a module-level (= global) variable for "1" instead of hardcoding it into A, you could do:

CURRENT_ATR_VALUE = 1
class A(object):
    def __init__(self):
        self.atr = CURRENT_ATR_VALUE

class B(object):
    def __init__(self):
        self.atr = A()

class C(object):
    def __init__(self):
        self.atr = A()


class D(object):
    def __init__(self, atr):
        global CURRENT_ATR_VALUE
        old = CURRENT_ATR_VALUE 
        CURRENT_ATR_VALUE = atr
        self.atr1 = B()
        self.atr2 = C()
        CURRENT_ATR_VALUE = old


test1 = D(atr=2)

This would have thge exact effect you are intending, could not be simpler - whithout requiring any of the Language's advanced introspection capabilities, and still would lead you soon to an unmaintainable mess. The way passing parameters around does contain the custom values in the scopes they are wanted, without side-effects, not even in a multi-threading or multi-processing running environment, and is far more recomendable.

If you really want to mess things around, you could create a factory function that would produce a new class "A" with the desired attributes, and inject it in the module global namespace as a new "A" class while you instantiate the others - that would be "fancier" and maybe is what you'd like. Just write A inside something like:

def A_factory(atr=1):    
    class A(object):
        def __init__(self, atr=1):
            self.atr = atr
    globals()["A"] = A

# creates default "A" class
A_factory(1)

And call this factory with your desired "atr" while instantiating "B" and "C" as above. This is absolutely unmanageable, but it is ultimately what you are asking for. T

Upvotes: 1

Related Questions