在 Python 中,我们经常会看到被双下划线包围的属性名和方法名,比如 __init__,__repr__,__future__,__all__,__version__,__author__。这种风格在 Python 中有很多的名字,最开始叫 magic variable 或 magic method。这样起名怎么看怎么别扭。
Dunder
是 Double UNDERscore
(中文双下划线)的缩写,分别取 Double
的 D
和 Underscore
的 Under
组成。这样取名后方便发音。在发明 dunder 之前, __init__ 要念作 double underscore init,其中的double underscore 有17个单词,发音是6声(嘴或舌头要变换7次动作,你可以以试试),而dunder 只有6个单词,发音是2声。
__init__
__init__:用于初始化的__init__方法在创建类的实例时不需要任何调用就会被调用,就像某些其他编程语言(如c++、Java、c#、PHP等)中的构造函数一样。
# declare our own string class
class String:
# magic method to initiate object
def __init__(self, string):
self.string = string
# Driver Code
if __name__ == '__main__':
# object creation
string1 = String('Hello')
# print object location
print(string1)
<main.String object at 0x7fe992215390>
__repr__
__repr__:当直接打印类的实例化对象时,系统将会自动调用该方法,输出对象的自我描述信息,用来告诉外界对象具有的状态信息。
但是,object 类提供的 repr() 方法总是返回一个对象(类名 + obejct at + 内存地址),这个值并不能真正实现自我描述的功能!如下:
class Person():
def __init__(self,name,age):
self.name = name
self.age = age
person = Person('zk', 20)
print(person)
print(person.__repr__())
<main.Person object at 0x7f5fe2bb4e50>
<main.Person object at 0x7f5fe2bb4e50>
因此,如果你想在自定义类中实现 “自我描述” 的功能,那么必须重写 repr 方法:
class Person():
def __init__(self,name,age):
self.name = name
self.age = age
def __repr__(self):
return 'Person类,有name和age两个属性'
person = Person('zk', 20)
print(person)
print(person.__repr__())
Person类,有name和age两个属性
Person类,有name和age两个属性
__add__
__add__:重载“+”运算符。
如尝试以下方式打印字符串:
# declare our own string class
class String:
# magic method to initiate object
def __init__(self, string):
self.string = string
# print our string object
def __repr__(self):
return 'Object: {}'.format(self.string)
# Driver Code
if __name__ == '__main__':
# object creation
string1 = String('Hello')
# concatenate String object and a string
print(string1 +' world')
会报以下错误:
TypeError: unsupported operand type(s) for +: ‘String’ and ‘str’
这时就需要添加 __add__
方法:
# declare our own string class
class String:
# magic method to initiate object
def __init__(self, string):
self.string = string
# print our string object
def __repr__(self):
return 'Object: {}'.format(self.string)
def __add__(self, other):
return self.string + other
# Driver Code
if __name__ == '__main__':
# object creation
string1 = String('Hello')
# concatenate String object and a string
print(string1 +' Geeks')
Hello Geeks
__file__
import os,sys
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
from lib import example
import HelloWorld
if __name__ == "__main__":
print(__file__)
print(example.__file__)
print(HelloWorld.__file__)
test.py