在研究一些python项目的源码时经常会看到一些特殊的方法和变量,比如两边双下划线__init__
定义的方法,还有一些类中会有以双下划线__
开头定义的变量,以及以单下划线_
开头的定义的变量。这里对目前经常遇到的做一个记录
__method__
:在class中有一些以双下划线开头和结尾的函数被称为特殊方法(Magic Method),更具体可以参考 官方文档
顺便说一下访问限制。如下(限制其实并不严格,主要靠自觉)
__
:在类内部如果使用双下划线开头定义变量,那么这个变量就变成了私有变量(private),即这个变量只有在内部访问(并不是绝对控制,可以通过其他方法访问)
_
:在类内部如果使用_开头定义变量,其实表示建议(表示可以从外部访问但最好不要访问)当成私有变量
特殊方法(Magic Method)
常用的内置方法简述如下
object.__new__(cls[, ...])
__new__
是一个静态方法用于创建对象并返回对象,当返回对象时会自动调用__init__
进行初始化。第一个参数是cls表示对象本身,其实self就是__new__
方法的返回值
object.__init__(self[, ...])
创建实例后由
__new__()
调用,但在返回给调用方之前调用。用于初始化实例,其中self表示实例本身
object.__str__(self)
当使用内置函数print()或format()时被调用,返回值只能是str.
__str__
方法默认调用了__repr__
方法
object.__dir__(self)
用于列出该对象内部的所有属性(包括方法)名,该方法将会返回包含所有属性(方法)名的序列。被dir(object)调用,调用会将序列返回为一个经过排序的列表
object.__call__(self[, args...])
将一个类实例要变成一个可调用对象,当实例被调用时触发。x() =
x.__call__()
例子:flask源码请求入口、django源码请求入口
object.__repr__(self)
跟
__str__
方法类似__repr__
它们都是一个“自我描述”的方法,不过repr偏向于程序员调试(应该更多的表示出一个对象来源的类以及继承关系)。
object.__setattr__(self, name, value)
试图分配属性时调用。这被调用而不是正常机制(即,将值存储在实例字典中)。name是属性名,value是要分配给它的值。app.abc = ‘mvalue’
object.__getattr__(self, name)
如果name被访问,同时它不存在的时候,此方法被调用。app.abc
object.__delattr__(self, name)
如果要删除name,这个方法就被调用
__setitem__
设置给定键的值。app[‘abc’]
__getitem__
返回键对应的值。app[‘abc’] = ‘mvalue’
__delitem__
删除给定键对应的元素
特殊属性
__name__
如果当前程序运行在当前模块中,那么__name__
就是__main__
,如果是被调用,这个模块中的__name__
就是模块名
|
|
|
|
__all__
如果一个模块定义了__all__
属性,则当被导入时,只有__all__
内指定的属性、方法、类可被导入
|
|
如上,如果通过from调用上面的模块,则只有__all__
里面定义的方法和类可以使用。如果使用其他未允许的,就会触发NameError: name 'xxx' is not defined
__slots__
跟__all__
不同,__slots__
可以用来限制类中实例的属性(这个限制只能限制当前类的实例,对子类没有影响)
|
|
如果视图设置不被允许的属性如x.tc
,就会抛出AttributeError: 'test_slots' object has no attribute 'tc'
,这个在Flask源码中的local对象有使用
__mro__
Python中每一个有父类的类都有这个属性,值是一个tuble。表示方法解析时的对象查找顺序: 越靠前的优先级越高
|
|
扩展问题
1. 什么是方法什么是函数
先扔下概念
function —— A series of statements which returns some value toa caller. It can also be passed zero or more arguments which may beused in the execution of the body
method —— A function which is defined inside a class body. Ifcalled as an attribute of an instance of that class, the methodwill get the instance object as its first argument (which isusually called self)
- 函数是Python中的可调用对象,即可以使用call运算符调用
- 方法是类中的函数。
2. 函数调用时加括号和不加括号的区别
不加括号表示调用函数本身,加括号就表示调用函数执行结果
|
|
3. super函数和mro方法的区别
super原理:通过mro()方法获取到实例的方法解析顺序,在mro顺序中返回当前类的下一个类
具体可以参考MRO 和 super