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 1 year ago.
I am looking for the possibility to add a variable amount of attributes to a class in python using a list.
class X():
def __init__(self,mylist):
for element in list:
self.element = ''
So if I have
tabs = ['food','name','map']
I will get a class with attributes as follows (pseudocode)
myclass = X(['food','name','map'])
print(X.food)
''
I will be able later on to modify X.food from other class.
LATE EDIT: The question: How to access object attribute given string corresponding to name of that attribute is similar but does not use a list to provide names or arguments to the class. Moreover in that particular question setattr is not used in any of the answers. Hence the answers of this question are the ones to follow.
You can use setattr.
class X:
def __init__(self, attrs):
for attr in attrs:
setattr(self, attr, "")
Use setattr:
class X():
def __init__(self,mylist):
for element in mylist:
setattr(self, element, '')
This adds the attributes to the class instance myclass, if you want to add to the class target X instead of self:
setattr(X, element, '')
Related
This question already has answers here:
In a Python object, how can I see a list of properties that have been defined with the #property decorator?
(5 answers)
Closed 2 years ago.
In Python, how can I get all properties of a class, i.e. all members created by the #property decorator?
There are at least two questions[1, 2] on stackoverflow which confound the terms property and attribute, falsely taking property as a synonym for attribute, which is misleading in Python context. So, even though the other questions' titles might suggest it, they do not answer my question.
[1]: Print all properties of a Python Class
[2]: Is there a built-in function to print all the current properties and values of an object?
We can get all attributes of a class cls by using cls.__dict__. Since property is a certain class itself, we can check which attributes of cls are an instance of property:
from typing import List
def properties(cls: type) -> List[str]:
return [
key
for key, value in cls.__dict__.items()
if isinstance(value, property)
]
This question already has answers here:
How do you change the value of one attribute by changing the value of another? (dependent attributes)
(1 answer)
Call Python Method on Class Attribute Change
(2 answers)
Detecting class attribute value change and then changing another class attribute
(1 answer)
Closed 2 years ago.
For example, I have a class:
import datetime
class Obj:
def __init__(self, attribute_1):
self.attribute_1 = attribute_1
self.last_edited = None
I want it to be able to do this:
# Creating object
obj1 = Obj("a")
obj1.attribute_1 = "b" # obj1.last_edited should have changed to datetime.datetime.now()
I'm not sure how to implement the changing of obj1's 'last_edited' attribute if I were to directly change obj1's 'attribute_1' (without any setters).
Thanks in advance.
All Python objects have a builtin method called __setattr__ that is called whenever a field in the class is changed. This method by default updates a value in the class dictionary (stored internally to represent the state of a class instance). You can override this behavior by defining a custom __setattr__ method. For your use case, the function might look like this:
class SomeObject:
def __init__(self, attr):
self.attr = attr
def __setattr__(self, name, value):
super().__setattr__("last_edited", time.time())
super().__setattr__(name, value)
Notice that we need to use a super call to avoid recursion (use the __setattr__ method of the base object class).
This question already has answers here:
What is getattr() exactly and how do I use it?
(14 answers)
Closed 3 years ago.
class Range:
GOOD=(1,100)
BAD=(200, 300)
class Test:
def test1(self):
key = get_map_key()
range = Range.key
What is the correct way to use constant defined in Range? The "key" is computed from a function. Possible value for "key" is GOOD, BAD.
If you want get the attribute of an object using a string you need use getattr function. With this function you can access to an object attribute with the name of that attribute as str:
class Test:
def test1(self):
key = get_map_key()#assuming it return 'BAD'
range = getattr(Range, key)
With this you have dynamic access to attributes. For this case it access to BAD property of Range class.
This question already has answers here:
Printing all instances of a class
(8 answers)
Closed 9 years ago.
Okay, so what I am trying to do is to create a function that will find an object instance based on the value of a specific attribute that all objects of the class share. Essentially, I want Python to search through the specific attribute of each instance of the class, and check it against another value, and if it finds a match to do some stuff. In pseudocode:
for each instance of Class:
if search_keyword is in instance.attribute:
do some stuff
found = True
if found is True:
tell_user("Found instance!")
If more detail is required on the nature of my inquiry, then:
What I am doing is essentially using the object as an extended dictionary. I have multiple attributes attached to the object, and I want to search through them. I am essentially using it as a storage container, which I need to search through.
If there is a better way to store said information other than objects, please share.
I'm essentially using it as a dictionary with multiple keys.
You could do this easily enough by having a class attribute which is a list of all instances of that class ever created, and having the __init__ of each instance of the class add the instance to the list.
class Foo(object):
list_of_all_foos = []
def __init__(self):
Foo.list_of_all_foos.append(self)
Then to search all the Foo instances you've created:
for foo_instance in Foo.list_of_all_foos:
if search_keyword is in foo_instance.attribute:
do some stuff
found = True
if found is True:
tell_user("Found instance!")
Alternatively, to do this with a class method, which might be a little more idiomatic:
class Foo(object):
list_of_all_foos = []
#classmethod
def create_foo_and_add_to_list(cls, *args, **kwargs):
new_foo = cls(*args, **kwargs)
Foo.list_of_all_foos.append(new_foo)
return new_foo
This question already has answers here:
How to avoid having class data shared among instances?
(7 answers)
Closed 9 years ago.
i just have a puzzling question abou class attributes in python.
consider the following class below:
class A:
__lst = []
def add(self, str):
self.__lst.append(str)
print len(self.__lst)
i tried to make two instances x and y and i got this:
>>> x = A()
>>> x.add('aaa')
1
>>> x.add('bbb')
2
>>> y = A()
>>> y.add('aaa')
3
>>> y.add('bbb')
4
i was expecting that the instance of y will have a separate copy of the list attribute but it seems that the list just gets bigger even if you use another object to add elements to the list. it's simply weird.
can anybody please enlighten me on this matter?
thanks a lot in advance for your help. :-)
If you define an attribute inside of the class body then it will be a class attribute, and it will be shared by all instances. In your code self.__lst is going to be a reference to A.__lst.
To have a separate list for each attribute, define it as self.__lst inside of the __init__() function:
class A(object):
def __init__(self):
self.__lst = []
def add(self, s):
self.__lst.append(s)
print len(self.__lst)
In addition to the change referenced above, I also made some minor modifications so that your code follows some Python best practices: inheriting from object (new-style class) and not using str (or any other built-in name) as a variable name.
Variables declared inside a class but not by means of self are class-level properties (like your __lst). They are equivalent to Java's static. If you want your property to be unique for all instances, you need to declare them via self (i.e., self.__lst).