Abstruction
Python has methods such as __init__
and __len__
that are represented by methodanme. Python is powered by the __ method. I'll explain how these work in Python. It's an article to understand how Python works, rather than how to use it.
Introduction of __
First, if you want to get the length of an object in Python, use len
. You can write it like the example below.
>>> len("hello")
5
>>> len([1, 2, 3])
3
>>> len({'a': 1, 'b': 2})
2
>>> len((1, 2, 3))
3
How does this actually work?
>>> "hello".__len__() # string
5
>>> [1, 2, 3].__len__() # list
3
>>> {'a': 1, 'b': 2}.__len__() # dict
2
>>> (1, 2, 3).__len__() # tuple
3
You can get the length of the object by calling __len__ ()
inside. That is, the function len ()
calls the object's __len__
. It works according to what the object itself has, rather than a Python function.
Let's implement mylen
to confirm the above.
>>> def mylen(object):
... 'Return length of the object'
... return object.__len__()
...
>>> mylen("hello")
5
>>> mylen([1, 2, 3])
3
>>> mylen({'a': 1, 'b': 2})
2
>>> mylen((1, 2, 3))
3
__membername__
How do you pronounce __len__
?
#First, let's pronounce each symbol accurately.
__len__
=> underbar underbar len underbar underbar #long!
#Let's omit the last underbar underbar.
=> underbar underbar len #long!!
#Since there are two underbars at the beginning, let's add double.
=> double underbar len #No, it's still long!!!
#Combine double and underbar to give it a new name.
=> dunder len
#So in the end it is pronounced dunder len.
#In the same way, it is customary to represent private`_membername`Also
_foo
=> single underbar foo
#Stick in the same way
=> sunder foo
#sunder foo Pronounced Thunder foo.
Python is working by calling the dunder member of the object.
For example, even if you use the +
operator, this is achieved by using this dunder method.
>>> 1 + 20
21
>>> (1).__add__(20)
21
When called with ʻobject [index]`, dunder getitem is called.
>>> "hello"[0]
'h'
>>> "hello".__getitem__(0)
'h'
Python works by using the dunder method. You can actually define the class yourself and deepen your understanding.
class Dog:
This time, let's say you have name and height. It is assigned to sunder name and sunder height, respectively.
def __init__(self, name, height):
self._name = name
self._height = height
This is a normal method, not one using dunder.
def bark(self):
print 'Woof! %s is barking' % self._name
bark can be called like this.
>>> dog = Dog("foo", 123)
>>> dog.bark()
Woof! foo is barking
dunder len This time the length of the Dog instance returns the height passed in the constructor.
def __len__(self):
return height
It is called by the build-in function len
like this.
>>> dog = Dog("foo", 123)
>>> len(dog)
123
>>> dog.__len__()
123
dunder getitem This time, if it is larger than the length of the dog instance (sunder height in this case), we will raise ʻIndexError`. The return value is index multiplied by 111.
def __getitem__(self, index):
if index >= len(self):
raise IndexError('Oops, index out of range')
return index * 111
It can be called with Dog [index].
>>> dog = Dog("foo", 123)
>>> dog[1]
111
>>> dog[2]
222
>>> dog[234]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "class_demo.py", line 18, in __getitem__
raise IndexError('Oops, index out of range')
IndexError: Oops, index out of range
>>> dog.__getitem__(1)
111
>>> dog.__getitem__(2)
222
>>> dog.__getitem__(234)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "class_demo.py", line 18, in __getitem__
raise IndexError('Oops, index out of range')
IndexError: Oops, index out of range
dunder call
A Dog instance defines a function that will be executed when () is called.
def __call__(self, action):
if action == 'fetch':
return '%s is fetching' % self.name
elif action == 'owner':
return 'Giwa'
else:
raise ValueError('Unknown action')
You can call it with Dog ("string").
>>> dog = Dog("foo", 123)
>>> dog('fetch')
'foo is fetching'
>>> dog('owner')
'Giwa'
>>> dog('name')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "class_demo.py", line 27, in __call__
raise ValueError('Unknown action')
ValueError: Unknown action
>>> dog.__call__('fetch')
'foo is fetching'
>>> dog.__call__('owner')
'Giwa'
>>> dog.__call__('name')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "class_demo.py", line 27, in __call__
raise ValueError('Unknown action')
ValueError: Unknown action
dunder add
If Dog instances are created, add both names and heights and take them as arguments to create a new Dog instance.
def __add__(self, other):
newname = self._name + '~' + other._name
newheight = self._height + other._height
return Dog(newname, newheight)
The + operator calls dunder add.
>>> dog1 = Dog("foo", 10)
>>> dog2 = Dog("bar", 20)
>>> dog3 = dog1 + dog2
>>> dog3.bark()
Woof! foo~bar is barking
>>> len(dog3)
30
>>> dog4 = dog1.__add__(dog2)
>>> dog4.bark()
Woof! foo~bar is barking
>>> len(dog4)
30
dunder str
It is used when called by str ()
or print
.
def __str__(self):
return 'I am a dog named %s' % self._name
It is called like this.
>>> dog = Dog('foo', 123)
>>> str(dog)
'I am a dog named foo'
>>> print dog
I am a dog named foo
>>> dog.__str__()
'I am a dog named foo'
'Demonstrate how Python classes and magic methods work'
class Dog:
'A simple canine class'
def __init__(self, name, height):
self._name = name
self._height = height
def bark(self):
print 'Woof! %s is barking' % self.name
def __len__(self):
return self._height
def __getitem__(self, index):
if index >= len(self):
raise IndexError('Oops, index out of range')
return index * 111
def __call__(self, action):
if action == 'fetch':
return '%s is fetching' % self._name
elif action == 'owner':
return 'Giwa'
else:
raise ValueError('Unknown action')
def __add__(self, other):
newname = self._name + '~' + other._name
newheight = self._height + other._height
return Dog(newname, newheight)
def __str__(self):
return 'I am a dog named %s' % self._name
_foo
is pronounced Thunder Fu__len__
is pronounced as DunderlenRecommended Posts