Python中单下划线和双下划线
首先看如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| >>> class MyClass(): ... def __init__(self): ... self.__superprivate = "Hello" ... self._semiprivate = ", world!" ... >>> mc = MyClass() >>> print(mc.__superprivate) Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: myClass instance has no attribute '__superprivate' >>> print(mc._semiprivate) , world! >>> print(mc.__dict__) {'_MyClass__superprivate': 'Hello', '_semiprivate': ', world!'}
|
_foo
: 单下划线是一种约定,用来指定变量私有(逻辑上的,其实仍可以访问).不能用 from module import *
导入,其他方面和公有一样访问.
__foo
: 解析器用 _<classname>__foo
来代替这个名字,以区别和其他类相同的命名,必须通过 对象名._类名__xxx
这样的方式进行访问.
__foo__
: Python 内部魔术方法,用来区别其他用户自定义的命名,以防冲突.例如 __init__()
,__del__()
,__call__()
等.
Python 常用魔术方法或属性
__abs__()
如果类实现了该方法,可通过 abs()
内置函数直接调用.如
1 2 3 4 5 6 7 8 9 10 11 12
| class C(int): def __init__(self, x): self._x = x
def __abs__(self): """ 通过 abs() 内置函数调用""" print("__abs__") return super().__abs__()
if __name__ == "__main__": c = C(-2) print(abs(c))
|
__eq__()
如果类实现了该方法,可通过 ==
判断两个对象是否相等.如
1 2 3 4 5 6 7 8 9 10 11 12 13
| class C(): def __init__(self, x, y): self._x = x self._y = y
def __eq__(self, other): print("__eq__") return self._x == other._x and self._y == other._y
if __name__ == '__main__': c = C("x", "y") d = C("x", "y") print(c == d)
|
__hash__()
如果类实现了该方法,可通过 hash()
内置函数直接调用.如
1 2 3 4 5 6 7 8 9 10 11
| class C(): def __init__(self, x, y): self._x = x self._y = y def __hash__(self): print("__hash__") return super().__hash__()
if __name__ == '__main__': c = C(1, 5) print(hash(c))
|
__iter__()
如果对象实现了可以返回迭代器的 __iter__
方法,那么对象就是可迭代的.
如果对象实现了该方法,可通过 iter()
函数直接调用.更多信息参见 Python 迭代器与生成器.
mro
此属性值为元组,子类在访问父类方法或属性时,会按照元组元素顺序寻找基类的方法或属性.如
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class A(): def foo(self): print("a.foo")
class B(A): pass
class C(A): def foo(self): print("c.foo")
class D(B, C): pass
d = D() d.foo() print(D.__mro__)
|
在方法解析期间寻找基类时要考虑的类的元组
__repr__()
与 __str__()
如果类实现了该方法,可通过 str()
内置函数直接调用.如
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class C(): def __init__(self, x, y): self._x = x self._y = y
def __repr__(self): print("__repr__") return "%s,%s" % (self._x, self._y)
def __str__(self): print("__str__") return super().__str__()
if __name__ == '__main__': c = C("x", "y") print(str(c))
|