0

Can a particular instance make its own variable in python, if yes would it be available to other instances of the class?

for eg:

class A():
    Var1 = 10

inst1 = A()

inst1.Var1 # will be 10

but can inst1 make it's own variables like Var2 etc and will these Variables be available to other class A instances like inst2?

In other Words, is a variable, which is bound to an instance of a class, accessible to another instance of the same class?

pranshu vinayak
  • 133
  • 1
  • 8
  • 2
    Can you give an example of what you want to do? This is a little confusing – Skam May 27 '18 at 17:41
  • A class can have "static" class variables that are shared between all instances - one changes it, all get the change. – Patrick Artner May 27 '18 at 17:41
  • 1
    what's an "own variable"? why wouldn't it be able to? available to other instances how? –  May 27 '18 at 17:42
  • Possible duplicate of [Instance variables vs. class variables in Python](https://stackoverflow.com/questions/2714573/instance-variables-vs-class-variables-in-python) – Patrick Artner May 27 '18 at 17:42
  • 1
    What exactly is meant by "make its own variable in python"? Do you mean can a class create variables with values specific to each instances? – Christian Dean May 27 '18 at 17:45
  • @Christian Dean He specifically asked to add a new attribute name (e.g. Var2) – Brian M. Sheldon May 27 '18 at 17:58
  • Do you want instances to create their own new variables dynamically or are you just asking about adding variables to an instance later? – Brian M. Sheldon May 27 '18 at 18:10
  • No he didn't @BrianM.Sheldon - not at first that is. [His _originally_ question said](https://stackoverflow.com/revisions/50554821/1) _"Can a particular instance make its own variable in python, if yes would it be available to other instances of the class?"_ Yes, the OP has edited his question now to clarify what he wants, but at the time it was not clear what he was asking for, and my comment was inquiring about his original post. – Christian Dean May 27 '18 at 19:33
  • An instance making its own variable is dynamic creation. The attribute name was a clarification. – Brian M. Sheldon May 27 '18 at 20:06

4 Answers4

1

To dynamically add attributes to a class or instance you can use setattr:

class MyClass(object):
    pass

my_instance = MyClass()


# add attribute to class
setattr(MyClass, 'new_attribute', 'added')

# Class now has attribute
print(MyClass.new_attribute == 'added')  # True

# Which is also available to instance
print(my_instance.new_attribute == 'added')  # True

# Add attribute to instance
setattr(my_instance, 'instance_only', 'yup')

# Instance now has attribute
print(my_instance.instance_only == 'yup')  # True

# Class does not have attribute
MyClass.instance_only # Raises AttributeError

# Add attribute to instances class
settatr(type(my_instance), 'instance_only', 'not anymore')

# Now the attribute is available to the class as well
print(MyClass.instance_only == 'not anymore')  # True

# New instances will also have the attributes
new_instance = MyClass()
print(new_instance.new_attribute == 'added')  # True

If you are not adding them dynamically see @gilch's answer

  • 1
    There is no reason to use `setattr` here; nothing is dynamic. – Daniel Roseman May 27 '18 at 17:52
  • An instance making its own variable is the definition of dynamic – Brian M. Sheldon May 27 '18 at 17:52
  • 1
    @DanielRoseman How would you propose adding a new variable without being dynamic – Brian M. Sheldon May 27 '18 at 17:59
  • 2
    `setattr` is only required if the attr name is unknown until runtime. E.g. a function that sets an attr typed in by the user. But they can still be set dynamically (i.e. at runtime) using the dot syntax if the name is known statically, e.g. a function that always assigns to the same name, but the user types in which object to use it on. – gilch May 27 '18 at 18:21
  • 1
    @gilch it all depends on what the OP's intention is, which is unclear from the question. – Brian M. Sheldon May 27 '18 at 18:25
1

Actually, the most common use case is for instances to have their "own" variables ("data attributes" in Python terminology) which are not shared between instances. The variables x and y below are examples of such "own" variables (every instance of class A gets its own variable x when the constructor is called, and inst1 also gets its own variable y later):

class A():
    def __init__(self):     # Constructor - called when A is instantiated
        self.x = 10         # Creates x for self only (i.e. for each instance in turn)

inst1 = A()
inst1.x = 15                # Changes x for inst1 only
inst1.y = 20                # Creates y for inst1 only
print(inst1.x, inst1.y)     # 15 20

inst2 = A()
print(inst2.x)              # 10
Ovaflo
  • 624
  • 6
  • 13
  • Okay, thanks for clearing my doubt. How is this concept different in java and other languages then? – pranshu vinayak May 27 '18 at 19:49
  • No conceptual difference. Instance variables (what you call "own" variables) are an important feature of object oriented programming. By the way, if your original question has been answered to your satisfaction, you should accept the best answer. – Ovaflo May 27 '18 at 21:05
0

It depends on if you set the variable in the class's dict or the instance's dict.

>>> class A:
    var = 10


>>> inst1 = A()
>>> inst2 = A()
>>> inst1.var  # not in instance, so looked up in class
10
>>> inst2.var
10
>>> inst2.var = 20  # instance attr shadows that from class
>>> inst2.var
20
>>> A.var = 30  # class attr can also be altered
>>> inst1.var
30
>>> inst2.var
20
>>> del inst2.var  # deleting instance attr reveals shadowed class attr
>>> inst2.var
30
>>> inst1.var2 = 'spam'
>>> inst2.var2  # new attr was set on inst1, so not available in inst2
Traceback (most recent call last):
  File "<pyshell#663>", line 1, in <module>
    inst2.var2
AttributeError: 'A' object has no attribute 'var2'
>>> inst1.__class__.var3 = 'eggs'  # same as A.var3 = 'eggs'
>>> inst2.var3  # new attr was set on the class, so all instances see it.
'eggs'
gilch
  • 10,813
  • 1
  • 23
  • 28
0

Even though the actual use may be questionable, you actually can bind new attributes to a class definition in a way that they are available to all instances of that class:

class A(object):
    attrib_one = 'VALUE'

    def add_class_attrib(self, name, value):
        # Bind new attribute to class definition, **not** to self
        setattr(A, name, value)

if __name__ == '__main__':
    # Instantiate _before_ changing A's class attributes
    a = A()
    b = A()
    # Add a new class attribute using only _one_ instance
    a.add_class_attrib('attrib_two', 'OTHER')
    # Print attributes of both instances
    print([e for e in dir(a) if not e.startswith('__')])
    print([e for e in dir(b) if not e.startswith('__')])

    # Create new instance _after_ changing A's class attribs
    c = A()
    # Print attributes of new instance
    print([e for e in dir(c) if not e.startswith('__')])

Running this code will print the following:

['add_class_attrib', 'attrib_one', 'attrib_two']
['add_class_attrib', 'attrib_one', 'attrib_two']
['add_class_attrib', 'attrib_one', 'attrib_two']

And you see, that -- even if a class attribute is added to the class definition after an instance of it has been created, the newly created class attribute in fact is available to all other instances of that (changed) class.

jbndlr
  • 4,965
  • 2
  • 21
  • 31