How to implement the title, do you think of it? You may be wondering what it is used for in the first place. In my case, I have a column-oriented library that can manipulate data with exactly the same IF as Pandas. I ran into this problem when I tried to make it myself.
#this(↓)How do you implement data access?
df['column_name']
I think that the implementation method like the title is the knowledge required when creating a public library etc. Personally, I was very impressed, so I posted this article.
To get data from your class in the form of object ['key'], you need to define a special method called \ _ \ _ getitem \ _ \ _.
class SampleClass:
def __init__(self):
self.dict = {'key': 'I got the key.'}
def __getitem__(self, key):
if not isinstance(key, str):
raise Exception()
return self.dict.get(key)
In the above sample code, SampleClass has dictionary type data (self.dict) in the field, and when SampleClass ['key'] is executed, \ _ \ _ getitem \ _ \ _ is called and it is dictionary type. It is a movement to retrieve the data paired with the key name key in the data.
Execution example
sample = SampleClass()
print(sample['key'])
Conversely, to define the behavior when adding data in the form of object ['key'] to your own class, use the special method \ _ \ _ setitem \ _ \ _.
class SampleClass:
def __init__(self):
self.dict = {}
def __setitem__(self, key, value):
if not isinstance(key, str):
raise Exception()
self.dict[key] = value
In the above sample code, \ _ \ _ setitem \ _ \ _ is called when the assignment process for SampleClass ['key'] is executed, and it is specified in the dictionary type data (self.dict) defined in SampleClass. It will be a movement to register the key / value pair.
Execution example
sample = SampleClass()
sample['key'] = 'I got the key.'
In this way, it is possible to give various behaviors to your own class by using special methods. Besides, if you want to define the behavior when using the + operator, for example, you can do it by using the \ _ \ _ add \ _ \ _ method.
class SampleClass:
def __init__(self, in_list):
self.list = in_list
def __add__(self, other):
if not isinstance(other, SampleClass):
raise Exception()
return SampleClass([*self.list, *other.list])
In the sample code above, when adding two SampleClass instances (when processed with the + operator), \ _ \ _ add \ _ \ _ is called to combine the list of the two instances (self.list). It will be a movement to create an instance of the new SampleClass.
Execution example
sample1 = SampleClass(['1', '2', '3'])
sample2 = SampleClass(['4', '5'])
sample3 = sample1 + sample2
If you need to consider adding instances of different types, you need to define the \ _ \ _ radd \ _ \ _ method in addition to the \ _ \ _ add \ _ \ _ method. (If the \ _ \ _ add \ _ \ _ method is not defined in the front class when viewed from the + operator, the \ _ \ _ radd \ _ \ _ method of the rear class will work.)
class SampleClass:
def __init__(self, in_list):
self.list = in_list
def __radd__(self, other):
if not isinstance(other, str):
raise Exception()
return SampleClass([*self.list, other])
The above sample code defines in the \ _ \ _radd \ _ \ _ method the behavior you would expect if your class (SampleClass) is after the + operator.
Execution example
sample = SampleClass(['1', '2', '3'])
sample2 = '4' + sample
Later, I personally found the \ _ \ _ repr \ _ \ _ method useful. This is a method that defines the character string to be displayed when the instance is called by the print function etc. By defining this, you can avoid the following display (probably everyone has experience).
<__main__.SampleClass object at 0x7f3d06feb3c9>
class SampleClass:
def __init__(self):
self.list = ['1', '2', '3']
def __repr__(self):
return '{}'.format(vars(self))
Execution example
sample = SampleClass()
print(sample)
Recommended Posts