Reputation: 21
I have a lot of properties, and
class ClassA:
@property
def func1(self):
self.__string1 = "a"
return self.__string1
@property
def func2(self):
self.__string2 = "b"
return self.__string2
def func3(self):
self.__list = [self.func1, self.func2]
seems redundant, especially when there are a lot of properties of a class. Is there a more compact way of doing this without having to list every single property?
Upvotes: 2
Views: 152
Reputation: 948
For the use case you propose you might want to take a look at data classes which allow you to avoid a lot of boiler plate. It also allows you to make it read-only with a simple frozen
argument. You could store all of your properties in a data class inside your class.
from dataclasses import dataclass
@dataclass(frozen = True)
class MyPropertyContainer():
property1: str
property2: float
# ...
Such a class would allow you to store all your read only properties in a single object which is easily accessible. The only down side is that you would need to access those properties through an additional dot from outside the class: my_object.my_properties.property1
or you could write properties assessors for each properties if you want to avoid that (which I do not recommend).
Afterwards, you can get all your arguments as a dict. If you need to you can extract a list from that. Provided you defined the data class above, it would look as follow:
my_properties = MyPropertyContainer('aString', 12, ...) # Instantiate what you want
properties_dict = my_properties.asDict() # Get the dictionnary
properties_list = list(properties_dict.values()) # Dict to list
Based on the example you provided, a solution would be to rewrite your class as follow:
# Make a data class for private properties
@dataclass(frozen = True)
class PropertyContainer():
func1: str
func2: str
class A():
# Since we're readonly we set the values on instanciation
def __init__(self, func1_val, func2_val):
self.properties = PropertyContainer(func1_val, func2_val)
# Here we get the values from all readonly
def func3(self):
return list(self.properties.asDict().values())
# You could also have sth like this for retro compatibility
@property
def func2(self):
return self.properties.func1
Upvotes: 0
Reputation: 409
Use the __dict__
attribute and combine it with the isinstance
method to filter out non property attributes:
> python
Python 3.10.1 (tags/v3.10.1:2cd268a, Dec 6 2021, 19:10:37) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> class A:
... not_a_property = None
... @property
... def func1():
... return "string1"
... @property
... def func2():
... return "string2"
...
>>> [p for p,v in A.__dict__.items() if isinstance(v, property)]
['func1', 'func2']
>>>
Upvotes: 1