py 特殊函数.md

方法 说明
__file__ 当前路径
__doc__ 描述类信息
__repr__/__str__ 打印/转换 print(X)、repr(X)/str(X)
__module__ 该函数所属模块的名称,没有则为 None
__name__ 如果当前模块为顶层模块执行 则打印main,作为被调用模块的时候打印当前模块的名称
__class__ 表示当前操作的对象的类是什么
__init__ 构造方法,通过类创建对象时,自动触发执行
__del__ 析构方法,当对象在内存中被释放时,自动触发执行
__call__ 所有的函数都是可调用对象。一个类实例也可以变成一个可调用对象,让调用更简单
__dict__ 查看类或对象中的所有成员
__slots__ 可以限制 class的属性
__getattr__ 当访问object不存在的属性时会调用该方法
__setattr__ 当设置类实例属性时自动调用,如j.name=5 就会调用setattr方法
__delattr__ 当删除类实例属性时自动调用,如del X.any 就会调用delattr方法
__getattribute__ 属性获取,当每次调用属性时,python会无条件进入getattribute中,不论属性存在与否
__add__ 运算符+
__sub__ 运算符-
__mul__ 运算符* 做乘数
__rmul__ 运算符* 做被乘数
__abs__ 绝对值
__or__ 运算符|
__iter__, __next__ 迭代 I=iter(X), next()
__getitem__ 用于索引操作,如字典。表示获取数据X[key],X[i:j]
__setitem__ 用于索引操作,如字典。表示设置数据X[key],X[i:j]=sequence
__delitem__ 用于索引操作,如字典。表示删除数据del X[key],del X[i:j]
__get__ 属性描述符的原理利用的是抽象的方法, X.attr
__get__ 属性描述符的原理利用的是抽象的方法, X.attr=value
__delete__ 属性描述符的原理利用的是抽象的方法, del X.attr
__new__ new:是用来创建实例的,对类实例化之前进行定制,在init之前创建对象
__metaclass__ metaclass:定义一个类如何被创建
__len__ 长度len(X)
__bool__ 布尔测试bool(X)
__lt__ X<Y
__gt__ X>Y
__le__ X<=Y
__ge__ X>=Y
__eq__ X==Y
__ne__ X!=Y
__radd__ 右侧加法 other+X
__iadd__ 实地(增强的)加法X+=Y(or else __add__)
__contains__ 成员关系测试item in X(X为任何可迭代对象)
__index__ 整数值hex(X), bin(X), oct(X)
__enter__, __exit__ 环境管理器with obj as var:

__file__

当前路径

__doc__

class Foo:
    """ 描述类信息,这是用于看片的神奇 """

    def func(self):
        pass

print Foo.__doc__
#输出:类的描述信息

__str__

如果一个类中定义了str方法,那么在打印 对象 时,默认输出该方法的返回值

repr 所返回的字符串应该准确、无歧义,并且尽可能表达出如何
用代码创建出这个被打印的对象。

reprstr 的区别在于,后者是在 str() 函数被使用,或
是在用 print 函数打印一个对象的时候才被调用的,并且它返回的字
符串对终端用户更友好。

class Foo:

    def __str__(self):
        return 'alex li'

obj = Foo()
print obj
# 输出:alex li

__module__

如果当前模块为顶层模块执行 则打印main
如果当前模块为被调用模块的时候 打印当前模块的名称

def fun():
    pass

print(fun.__module__)

__name__

打印函数名称

def fun():
    pass

print(fun.__name__)

__class__

表示当前操作的对象的类是什么

from lib.aa import C

obj = C()
print obj.__module__  # 输出 lib.aa,即:输出模块
print obj.__class__      # 输出 lib.aa.C,即:输出类

__init__

构造方法,通过类创建对象时,自动触发执行

class Role(object):    
#初始化函数,在生成一个角色时要    初始化的一些属性就填写在这里    
    def __init__(self,name,role,weapon,life_value=100,money=15000):

#__init__中的第一个参数self,和这里的self都 是什么意思? 看下面解释
self.name = name
        self.role = role

__del__()

析构方法,当对象在内存中被释放时,自动触发执行

class Role(object):
    def __init__(self,name,role,weapon:
        self.name = name
        self.role = role
        self.weapon = weapon

    def __del__(self):             #析构函数
        print("del.....run...")
r1 = Role('Alex','police','AK47')    #生成一个角色

__call__()

#所有的函数都是可调用对象。
#一个类实例也可以变成一个可调用对象,特殊方法__call__()。
# 让调用更简单

class Person(object):
    def __init__(self, name, gender):
        self.name = name
        self.gender = gender

    def __call__(self, friend):
        print 'My name is %s...' % self.name
        print 'My friend is %s...' % friend
现在可以对 Person 实例直接调用:

>>> p = Person('Bob', 'male')
>>> p('Tim')
My name is Bob...
My friend is Tim...

__dict__

查看类或对象中的所有成员

print(类.__dict__) # 打印类里所有属性,不包括实例属性
print(实例.__dict__) #打印实例所有属性,不包括类属性

__slots__

可以限制 class的属性

参考: [Python] dir() 与 dictslots 的区别

使用slots

在默认情况下,Python 的新类和旧类的实例都有一个字典来存储属性值。这对于那些没什么实例属性的对象来说太浪费空间了,当需要创建大量实例的时候,这个问题变得尤为突出。
  因此这种默认做法可以通过在新式类中定义一个 slots 属性从而得到解决。slots 声明中包含若干实例变量,并为每个实例预留恰好足够的空间来保存每个变量,因为没有为每个实例都创建一个字典,从而节省空间。

__getattr__

当访问object不存在的属性时会调用该方法

定义了__getattr__(),当访问object不存在的属性时会调用该方法

不定义访问不存在的属性时会报 AttributeError

eg:

class Cat(object):
  def __init__(self):
    self.name = "jn"

  def __getattr__(self, item):
    return "tm"


cat = Cat()
print(cat.name)
print(getattr(cat, 'name'))
print("*" * 20)
print(cat.age)
print(getattr(cat, 'age'))

__setattr__

当设置类实例属性时自动调用,如j.name=5 就会调用setattr方法

class Dict(dict):

    def __getattr__(self, key):
        try:
            return self[key]
        except KeyError:
            raise AttributeError(r"'Dict' object has no attribute '%s'" % key)

    def __setattr__(self, key, value):
        self[key] = value

d = Dict(a=1, b=2)
print (d['a'])
print (d.a) #调用类中原本没有定义的属性时候,调用__getattr__
d.a = 100 #对实例的属性进行赋值的时候调用__setattr__
print (d['a'])

__getattribute__

当每次调用属性时,python会无条件进入getattribute中,不论属性存在与否,这就是与getattr的区别

必须特别小心 getattribute() 方法,因为 Python 在查找类的方法名称时也将对其进行调用。

__getitem__、__setitem__、__delitem__

用于索引操作,如字典。以上分别表示获取、设置、删除数据

class Foo(object):

    def __getitem__(self, key):
        # 使对象可以支持取值,切片,迭代
        print('__getitem__',key)

    def __setitem__(self, key, value):
        print('__setitem__',key,value)

    def __delitem__(self, key):
        print('__delitem__',key)

obj = Foo()

result = obj['k1']      # 自动触发执行 __getitem__
obj['k2'] = 'alex'   # 自动触发执行 __setitem__
del obj['k1']

__get__,__set__,__delete__

属性描述符的原理利用的是抽象的方法, 把十几个字段共同的特性抽出来

class Int_validation:
    def __get__(self, instance, owner):
        return  self.value
    def __set__(self, instance, value):
        if  isinstance(value,int) and 0<value<100:
            self.value=value        #这个要注意 要用value,不能用instance 否则会陷入死循环
        else:
            print("请输入合法的数字")
    def __delete__(self, instance):
        pass

class Student:
    age=Int_validation()

stu=Student()   
stu.age=50
print(stu.age)

__new__/__metaclass__ *(自定义类)

参考: https://www.jianshu.com/p/224ffcb8e73e

new:是用来创建实例的,对类实例化之前进行定制,可以用到。
metaclass:定义一个类如何被创建
类的生成 调用 顺序依次是 new –> init –> call

#创建类特殊方式
def func(self):
    print(self.name,self.age)

def __init__(self,name,age):
    self.name = name
    self.age = age

#通过Type实例化产生的Foo类,Foo是Type的对象。
#(object,)加入“,”是为了让括号知道他是个元组。
#type第一个参数:类名
#type第二个参数:当前类的基类
#type第三个参数:类的成员
Foo = type('Foo',(object,),{'talk':func,
                            '__init__':__init__})

f= Foo("Chrn",22)
f.talk()
print(type(Foo))
#Type 为 类的类,所有类都是Type创建的
class Metaclass(type):
    def __new__(cls, name, bases, dct):
        print 'HAHAHA'
        dct['a'] = 1
        return type.__new__(cls, name, bases, dct)

print 'before Create OBJ'
class OBJ(object):
    __metaclass__ = Metaclass
print 'after Create OBJ'

if __name__ == '__main__':
    print OBJ.a

__add__

对象相加直接执行

class foo:
def __init__(self,name,age):
self.name=name
self.age=age
def __add__(self, other):
        temp="%s-%d"%(self.name,other.age)
return temp

obj1=foo("aaa",123)#对象1
obj2=foo("bbb",455)#对象2
print("对象1",obj1)
print("对象2",obj2)
print('---自动执行add方法--------')
ret=obj1+obj2 #self代表obj1,other代表obj2
print("add方法",ret)

__iter__

生成器作用,返回值可以被迭代,需要使用for执行iter方法

class foo:
def __iter__(self):
return iter([11,22,33,44,55])

obj=foo()
for item in obj:#for默认执行iter方法,拿到返回值,for需要一个可以被循环的东西(obj)
    print(item)

__enter__, __exit__

with语句的时候使用
基本思想是with所求值的对象必须有一个enter()方法,一个exit()方法。
紧跟with后面的语句被求值后,返回对象的enter()方法被调用,这个方法的返回值将被赋值给as后面的变量。当with后面的代码块全部被执行完之后,将调用前面返回对象的exit()方法

class Sample:
    def __enter__(self):
        print("In __enter__()")
        return "Foo"

    def __exit__(self, type, value, trace):
        print("In __exit__()")

def get_sample():
    return Sample()

with get_sample() as sample:
    print("sample:", sample)

仅供参考
目录