0

If I create a class like below:

class Foo(object): 
     foo = {'useful_info': 'useful_info'}  
     def __init__(self, foo, bar): 
         self.foo['foo'] = foo 
         self.bar = bar 

and I create an instances of it and print it's attributes as:

Foo1 = Foo('foo1', 'bar1')
print(Foo1.foo)
print(Foo1.bar)

I get the output:

Foo1 = Foo('foo1', 'bar1')
print(Foo1.foo)
print(Foo1.bar)

However, now if I create a new instance named Foo2 and print the attributes of both Foo1 and Foo2 as:

Foo2 = Foo('foo2', 'bar2')

print("Foo2.foo: ", Foo2.foo) 
print("Foo2.bar: ", Foo2.bar) 
print("Foo1.foo: ", Foo1.foo) 
print("Foo1.bar: ", Foo1.bar)

I get the output:

Foo2.foo:  {'foo': 'foo2'}
Foo2.bar:  bar2
Foo1.foo:  {'foo': 'foo2'}
Foo1.bar:  bar1

The string attributes bar have been set as I expect, but the dictionary foo has been updated for both instances of Foo.

I can get round this by declaring the dict foo in the init magic method as:

class Foo(object): 
     def __init__(self, foo, bar): 
         self.foo = {'useful_info': 'useful_info'} 
         self.foo['foo'] = foo 
         self.bar = bar 

but now the dictionary foo containing 'useful_info' isn't accessible until the init function is called i.e. if I use the line: Foo.foo I get an AttributeError.

Is there any way to create a new dictionary containing some 'useful_infomation' so that the useful info is accessible before the class is initialised and every new instance of a class has a different instance of this dictionary.

2 Answers 2

1

You can make a copy.deepcopy of the dictionary within __init__ so each instance has a deep copy of the dictionary, instead of sharing the same foo dictionary object.

import copy

class Foo(object): 
    foo = {'useful_info': 'useful_info'}  
    def __init__(self, bar): 
        self.foo = copy.deepcopy(Foo.foo)
        self.bar = bar
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks! Though I think the self.foo['foo']... line should be replaced with self.foo = copy.deepcopy(self.foo)
But, why do they share the same foo object ?
The original question had the argument 'foo' being set as a value under the key 'foo' of the dict foo. I understand this probably wasn't the best naming system! To answer this while keeping the functionality of the original question the dict foo would have to be re-created in the init and in that new dict the key foo should be set to the argument foo. Though I agree this pretty much answers my question.
1

Just combine both:

class Foo:
    foo = {'useful_info': 'useful_info'}
    def __init__(self, foo, bar):
        self.foo = {'useful_info': 'useful_info'}
        self.foo['foo'] = foo
        self.bar = bar 

2 Comments

Wouldn't foo['useful_info'] be overwritten by the call of __init()__ ? If it was used and modified before that call, wouldn't it be an issue ?
@AniMir the class variable would not be modified, because an instance variable with the same name is created the line above it... self.foo = {'useful_info': 'useful_info'}

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.