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))
 
 
 
 
 
   |