Python dunder/magic 方法
- `__init__`
- `__repr__`
- `__add__`
- `__file__ `
在 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)
__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__())
因此,如果你想在自定义类中实现 “自我描述” 的功能,那么必须重写 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__
- __file__:该变量包含了现在被 import 的moudle 的路径。
下面两种写法会分别给出相对路径和绝对路径: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
…/lib/example.cpython-38-x86_64-linux-gnu.so
/sda/项目资料/27.pybind11/scripts/HelloWorld.py