Python, object gets the values of the new one [duplicate] - python

This question already has answers here:
How to avoid having class data shared among instances?
(7 answers)
Closed 9 years ago.
I have the following code:
import math
class h:
vektor = [0,0]
rel_chyba = 0
def __init__(self, hodnota, chyba):
self.vektor[0] = hodnota
self.vektor[1] = chyba
self.rel_chyba = chyba*1.0/hodnota
def __rmul__(self, hod2):
return h(hod2.vektor[0]*self.vektor[0], math.sqrt(self.rel_chyba*self.rel_chyba+hod2.rel_chyba*hod2.rel_chyba))
v = h(12,1)
print v.vektor[1]
t = h(25,2)
print v.vektor[1]
My problem is, that v.vektor[1] prints 1 for the first time and 2 for the second time. All the attributes of the object v are assigned the values of the attributes from t.
How can I create two different objects?
Thanks for your answers

Don't declare vektor at class level, that makes it a class variable. Just declare it inside __init__:
def __init__(self, hodnota, chyba):
self.vektor = [hodnota, chyba]

Related

How to create an instance of a class from a string name of the instance? [duplicate]

This question already has answers here:
How do I create variable variables?
(17 answers)
Closed 2 years ago.
I would like to create several instances of a Class, I tried to make a for loop to name them differently.
Something like this, which doesn't work because the instance name is not supposed to be a string:
class A:
pass
for i in range(10):
"a"+str(i) = A()
Here the result I expect is 10 instances of the class A named: a0, a1, ... , a9.
How should I do?
You can use dictionaries,
classes = {}
for i in range(10):
classes[f"a{i}"] = A()
Then you can access the class instance like this classes["a7"].
i can think in two ways.
The trash way and a good way
Thrash:
class A:
pass
for i in range(10):
eval("a"+str(i)) = A()
Good:
class A:
pass
a= []
for i in range(10):
a[i] = A()

Have a Function Take a Variable Name of an Object [duplicate]

This question already has answers here:
How to access (get or set) object attribute given string corresponding to name of that attribute
(3 answers)
Closed 4 years ago.
If I have the following code:
class foo:
def __init__(self):
self.w = 5
self.z = 10
def sum(obj,x,y):
return obj.x+obj.y
f = foo()
print sum(foo,'x','y')
How would I create a function that takes in two unkown variable names and returns the sum of those variables variables?
In this case the example should print 15.
EDIT:
Typo for the last line it should say print sum(foo,'w','z')
All (I think?) python objects have a built-in __getattribute__ method. Use it like this:
def sum(obj,x,y):
return obj.__getattribute__(x)+obj.__getattribute__(y)
The method takes a string, and "unpacks" it to being a variable name.

Updating a list in a class, in a list [duplicate]

This question already has answers here:
How to avoid having class data shared among instances?
(7 answers)
Should I use instance or class attributes if there will only be one instance? [closed]
(4 answers)
Closed 7 years ago.
In Python 3, I have a list of classes, and each class has a list in it. I'm having difficulties updating those lists. As so:
class Item():
newPrice = 0
prices = [0]
def __init__(self, _prices):
self.prices = _prices
items = [Item([10]), Item([20]), Item([30])]
for item in items:
item.newPrice = SomeFunction()
item.prices.append(item.newPrice)
The function SomeFunction() is an elaborate function that retrieves a different value for each Item instance.
For some reason, each Item instance in the items list has the same value for prices, which is a list that contains the newPrice value for each Item instance. I hope this is clear enough.
What am I missing?
You should define prices as instance attribute, instead of class attribute, because class attributes are shared between all instances:
class Item():
def __init__(self, _prices):
self.newPrice = 0
self.price = _prices

Issue with Python class that has a list [duplicate]

This question already has answers here:
python: class attributes and instance attributes
(6 answers)
Closed 8 years ago.
I have a simple question:
Say that I have the following class:
class step:
alpha = []
and my main has the following:
listofstep = []
for i in range(20):
z = step()
z.alpha.append(0)
listofstep.append[z]
why does len(listofstep[0].alpha) gives me 20?
As you define it, alpha is a class variable and not an instance variable. When you do z.alpha it always points at the same list, regardless of which instance it is. Try to define step like this:
class step:
def __init__(self):
self.alpha = []

How to instantiate a class given its name as a string? [duplicate]

This question already has answers here:
Calling a function of a module by using its name (a string)
(18 answers)
Closed 8 years ago.
Give some class definitiona in python, e.g.
class A(object):
def __init__(self):
self.x = 5
class B(object):
def __init(self):
self.x = 42
I want to instantiate one of these classes given its name as string. So for example, if classname is A, then I want to do something like
myinstance = SOMETHING(classname)
which should correspond to
myinstance = A()
Is there a way to do this without the use of eval eval or maps? If not, I would do the following:
map = {'A': A, 'B': B}
myinstance = map[classname]()
Considering that the Python naming scheme is based on maps, you will be using maps of one sort or another even if you use eval.
Building your own map is the most appropriate, but you can also use globals() or retrieve it from a module if your classes are stored somewhere else:
import util_module
getattr(util_module, 'A') ()

Categories