Python用下划线作为变量前缀和后缀指定特殊变量
_xxx不能用’frommoduleimport*’导入
__xxx__系统定义名字
__xxx类中的私有变量名
核心风格:避免用下划线作为变量名的开始。
因为下划线对解释器有特殊的意义,而且是内建标识符所使用的符号,我们建议程序员避免用下划线作为变量名的开始。一般来讲,变量名_xxx被看作是“私有的”,在模块或类外不可以使用。当变量是私有的时候,用_xxx来表示变量是很好的习惯。因为变量名__xxx__对Python来说有特殊含义,对于普通的变量应当避免这种命名风格。
“单下划线”开始的成员变量叫做保护变量,意思是只有类对象和子类对象自己能访问到这些变量;“双下划线”开始的是私有成员,意思是只有类对象自己能访问,连子类对象也不能访问到这个数据。
以单下划线开头(_foo)的代表不能直接访问的类属性,需通过类提供的接口进行访问,不能用“fromxxximport*”而导入;以双下划线开头的(__foo)代表类的私有成员;以双下划线开头和结尾的(__foo__)代表python里特殊方法专用的标识,如__init__()代表类的构造函数。
现在我们来总结下所有的系统定义属性和方法,先来看下保留属性:
>>>Class1.__doc__#类型帮助信息'Class1Doc.'>>>Class1.__name__#类型名称'Class1'>>>Class1.__module__#类型所在模块'__main__'>>>Class1.__bases__#类型所继承的基类(
序号目的所编写代码Python实际调用①获取一个计算属性(无条件的)x.my_propertyx.__getattribute__('my_property')②获取一个计算属性(后备)x.my_propertyx.__getattr__('my_property')③设置某属性x.my_property=valuex.__setattr__('my_property',value)④删除某属性delx.my_propertyx.__delattr__('my_property')⑤列出所有属性和方法dir(x)x.__dir__()
可以让类的实例变得可调用——就像函数可以调用一样——通过定义__call__()方法。
zipfile模块通过该方式定义了一个可以使用给定密码解密经加密zip文件的类。该zip解密算法需要在解密的过程中保存状态。通过将解密器定义为类,使我们得以在decryptor类的单个实例中对该状态进行维护。状态在__init__()方法中进行初始化,如果文件经加密则进行更新。但由于该类像函数一样“可调用”,因此可以将实例作为map()函数的第一个参数传入,代码如下:
如果类作为一系列值的容器出现——也就是说如果对某个类来说,是否“包含”某值是件有意义的事情——那么它也许应该定义下面的特殊方法已,让它的行为方式与序列类似。
我将此内容从前一节中拿出来使其单独成节,是因为“比较”操作并不局限于数字。许多数据类型都可以进行比较——字符串、列表,甚至字典。如果要创建自己的类,且对象之间的比较有意义,可以使用下面的特殊方法来实现比较。
如果定义了__lt__()方法但没有定义__gt__()方法,Python将通过经交换的算子调用__lt__()方法。然而,Python并不会组合方法。例如,如果定义了__lt__()方法和__eq()__方法,并试图测试是否x<=y,Python不会按顺序调用__lt__()和__eq()__。它将只调用__le__()方法。
*要重建序列化对象,Python需要创建一个和被序列化的对象看起来一样的新对象,然后设置新对象的所有属性。__getnewargs__()方法控制新对象的创建过程,而__setstate__()方法控制属性值的还原方式。
以下是withfile习惯用法的运作方式:
真正神奇的东西
如果知道自己在干什么,你几乎可以完全控制类是如何比较的、属性如何定义,以及类的子类是何种类型。