I have a simple class called Storage
that has many methods and properties.
For this question, I’m only interested in making uniques
a classmethod and a property in the same time. I don’t know if this is possible. I wonder if there is a dynamic processing : based on if uniques
is being called from the class or an object, then we should always have the same result for the same input used (here it’s data
).
class Storage:
def __init__(self, data):
self.data = data
@classmethod
def uniques(cls, data=None):
if data is None:
data = cls.data
return [list(set(item)) for item in data]
Unfortunately, when I try doing both calls one is working but the second one gives error :
data = [["apple", "banana", "apple"], ["cat", "dog", "dog"], ["red", "blue", "red"]]
print(Storage.uniques(data))
# [["banana", "apple"], ["cat", "dog"], ["blue", "red"]]
########################################
print(Storage(data).uniques())
5 @classmethod
6 def uniques(cls, data=None):
7 if data is None:
----> 8 data = cls.data
9 return [list(set(item)) for item in data]
AttributeError: type object 'Storage' has no attribute 'data'
Can you guys show me how to deal with that ? Is this even possible ?
0
The following works but is ugly and I wouldn’t recommend to use it:
class Storage:
def __init__(self, data):
self.data = data
self.uniques = lambda: self.__class__.uniques(data)
@classmethod
def uniques(cls, data):
return [list(set(item)) for item in data]
# Testing
data = [["apple", "banana", "apple"], ["cat", "dog", "dog"], ["red", "blue", "red"]]
print(Storage.uniques(data))
print(Storage(data).uniques())
It creates for each instance a new method (using lambda
) bound to this instance only. The attribute lookup mechanism will find this method first if it is applied to the instance.
3
I just wanted to try it. I think this is what you are looking for.
class Storage:
def __init__(self, data):
self.data = data
def uniques(instance_or_data):
if isinstance(instance_or_data, Storage):
data = instance_or_data.data
else:
data = instance_or_data
print(data)
Storage.uniques('X')
X
Storage('X').uniques()
X
Storage('Y').uniques()
Y
Storage.uniques('Y')
Y
1
Please try this:
class Storage:
data = []
def __init__(self, data):
setattr(Storage, 'data', data)
@classmethod
def uniques(cls, data=None):
if data is None:
data = cls.data
return [list(set(item)) for item in data]
data = [["apple", "banana", "apple"], ["cat", "dog", "dog"], ["red", "blue", "red"]]
print(Storage.uniques(data))
print(Storage(data).uniques())