博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python-builtin学习
阅读量:3515 次
发布时间:2019-05-20

本文共 5767 字,大约阅读时间需要 19 分钟。

python类中内置方法

在python中,创建一个类时我们可以看到有好多我们并没有在类中实现的方法,类似于__new__,__init__这样的方法,这些方法就是python类中的内置方法,而根据其用法我大体把他们分为三大类1. 功能性方法,类似于__new__是对类实例化一个对象,__init__是对类实例化一个对象之后的初始化方法,这一类某些功能会用到的,我称之为功能性方法2. 符号类方法,类似于__add__是在使用实例化的对象与另一个对象用符号"+"相连时调用的方法, 类似的还有(),-,>,

功能性内置方法

  • __ new __

此内置方法在Python2.X中存在于新式类中,即类显示继承了object,在Python3.X中全部存在

此方法用于实例化一个类对象,在object中作为一个staticmethod存在,直接类名+方法即可调用

class object:    @staticmethod    def __new__(cls, *more):        pass

各类中可以重写此方法,最终会调用object.__new__方法在内存中创建一个对象

在初始化一个类对象时,基本的逻辑是,先通过__new__实例化一个对象,然后return,而__init__方法接收的第一个参数self,就是new返回的此类实例化的对象

第一步会通过new方法来实例化一个对象,如果没有对__new__进行重构的话,那么会调用object初始化一个此类的对象

__new__方法也可以通过重写,来用别的类的方法来实现初始化一个对象,如下:

class A(object):    def __new__(cls, *args, **kwargs):        print("A.__new__")        return object.__new__(cls, *args, **kwargs)class B(object):    def __new__(cls, *args, **kwargs):        print( "B.__new__" )        return A.__new__(cls, *args, **kwargs)    def __init__(self):        print("my is B")>>>b = B()B.__new__A.__new__my is B

重点需要主要的是:当__new__方法中返回的不是此类的实例化对象,即使是父类的实例化对象,也不会调用__init__方法,所以此处需要注意

new方法的应用场景

单例模式

class Singleton(object):    def __new__(cls, *args, **kwargs):        if not hasattr(cls, "_instance"):            _instance = super(Singleton, cls).__new__(cls, *args, **kwargs)            setattr(cls, "_instance", _instance)        return getattr(cls, "_instance", _instance)class Test(Singleton):    def __init__(self, test):        self.test = test>>>a=Test("123")>>>print(a, id(a), a.test)(<__main__.Test object at 0x7f1e524a8b90>, 139768206363536, '123')>>>b = Test("234")>>>print(b, id(b), b.test)(<__main__.Test object at 0x7f1e524a8b90>, 139768206363536, '234')>>>print(a, id(a), a.test)(<__main__.Test object at 0x7f1e524a8b90>, 139768206363536, '234')
  • __ init __

__init__方法接收__new__方法实例化出来的本类的对象,然后可以在此方法中设置一些对象的属性,或者其他方法的调用都可以

  • __ enter __/__ exit __

在python中使用关键字with进行上下文管理时,会使用到此方法,举例说明:

class Context(object):    def __init__(self):        print("my is init")    def __enter__(self):        print("my is enter")    def __exit__(self, *args):        print("my is exit")with Context() as a:    print(a)my is initmy is enterNonemy is exit

根据上面的例子可以看出来,使用with时会进入到enter函数之内,并且是在init之后,同时enter返回值是作为a来使用,在with作用域结束之后,将会执行__exit__函数

下面再来一个例子,来进一步证明enter的返回值

class Test1(object):    def __init__(self, name):        self.name = nameclass Context(object):    def __init__(self, name):        self.name = name    def __enter__(self):        return Test1(self.name)    def __exit__(self, *args):        passwith Context("123") as a:    print(a.name)123

上面应该就是比较直观的看到了enter返回的对象作为a来使用。

下面是延伸出来的,python内置的上下文管理的类库contextlib

from contextlib import contextmanager@contextmanagerdef make_context():    print( 'enter' )    try:        yield {}    except:        print( "error" )    finally:        print 'exit'with make_context() as m:    print menter{}exit

基本上还是和类的原理类似,还是利用了enterexit,只是在其中加入了生成器的使用,大概原理如下:

使用contextmanager装饰器的函数必须是一个生成器contextmanager的原理就是返回一个Generate的类基本步骤也是在走三个函数__init__函数, 初始化生成器self.gen__enter__函数, 调用next(self.gen) 这样就会将生成器中yield的值返回__exit__函数, 捕捉错误异常等信息,调用next,正常应该会返回stop error,如果未返回错误,那就手工返回错误。

符号类内置方法

  • __ call __

在初始化类对象之后,使用instance()时调用此内置方法,可以在此内置方法中做一些想做的事情

class A(object):    def __init__(self):        pass    def __call__(self, *args):        print "A.call"        print args>>>a = A()>>>a(1) # 在类对象使用()符号时,就会调用__call__方法,A.call(1,)

基于此,可以编写相应的类装饰器

class func_decorate(object):    def __init__(self, func):        self.func = func    def __call__(self, *args, **kwargs):        self.func(*args, **kwargs)@func_decoratedef function1(*args, **kwargs):    pass

还有一些其他方面的应用还需要探索,但是要明确此内置方法时在直接执行实例对象()时调用,那应用万变不离其宗。

  • __ gt __

像我们对两个对象进行比较时,例如a>b,或者a==b,实质在执行时都是在执行a对象的__gt__类似方法,__gt__表示”>”,举个例子如下

class A(object):    def __init__(self):        pass    def __gt__(self, y):        print "A.gt"        print "123">>>a = A()>>>b = A()>>>print a>bA.gt123None

上述的例子我们可以看到,在进行比较时执行的是__gt__内置方法,而我们自己已经给重写了,但是这里看到最后还输出一个None,以及__gt__除了self之外,还需要另外一个参数y,就是用来比较的参数,同时__gt__也需要一个输出值,而如果没有输出值的话,python默认会输出一个None值。

  • __ add __

当我们将两个int值相加时,那么是怎么变成一个新的值呢?其实质是在int类中,根据计算结果,将变量的指针指向内存中的另一个值,所以我们在进行“+”操作时,实质就是执行类中的内置函数add,下面我们写一个例子测试一下。

class A(object):    def __init__(self):        pass    def __add__(self, y):        print "A.add"        print self        print y>>>a = A()>>>b = A()>>>print a>bA.add<__main__.A object at 0x7fef0c184e50><__main__.A object at 0x7fef0c101ef0>None
  • __ or __

当我们将两个对象通过符号“|”连接时,实质会调用内置方法__or__,具体用法与上述的例子基本想吃。

还有一些其他的内置函数不再一一列出,在下表中单独摘出一部分,对应关系如下

函数名 对应符号 描述
__getitem__ x[y] 获取元素
__setitem__ x[y]=z 设置元素
__delitem__ del x[y] 删除元素
__delslice__ del x[a:b] 切片删除,del x[a:b] 调用x对象 x.__delslice__()
__gelslice__ x[a:b] 切片获取
__call__ () 实例对象执行时的操作,x(*args, **kwargs)<==> x.__call__(*args,**kwargs)
__gt__ > 实例化对象进行大小比较时,x>y <==> x.__ gt__(y)
__ge__ >= 实例化对象进行大小比较时,x>=y <==> x.__ ge__(y)
__lt__ < 实例化对象进行大小比较时,x x.__ lt__(y)
__le__ <= 实例化对象进行大小比较时,x<=y <==> x.__ le__(y)
__eq__ == 实例化对象进行大小比较时,x\==y <==> x.__ eq__(y)
__ne__ != 实例化对象进行大小比较时,x!=y <==> x.__ ne__(y)
__add__ + 实例化对象进行加法时,x+y <==> x.__add__(y)
__mul__ * 实例化对象进行乘法法时,x*y <==> x.__mul__(y)
__mod__ % 取余操作
__div__ / 取商操作
__or__ | 或比较
__and__ & 和比较
__index__ x[y:z] 取值 x[y:z] <==> x[y.__index__():z.__index__()
__floordiv__ //
__lshift__ <<

内置函数类内置方法

Python中部分内置函数或者内置类与类内置函数的对应关系如下表

函数名 对应内置函数/类 描述
__getattrbuite__ getattr(x, “name”) 获取x对象的name属性,调用x对象的__getattrbuite__(self, name)方法
__setattr__ setattr(x, name, value) 给对象设置某属性时,调用__setattr__方法
__delattr__ delattr(x, name) 删除某对象某属性时,调用__delattr__方法,del x.name 也会调用
__str__ str(a) 使用内置类str,对对象a处理时,调用对象a的内置方法__str__
__len__ len(a) 使用内置方法len,对对象a进行len(a)处理时,调用对象a的内置方法__len__
__abs__ abs(a) 使用内置方法abs,对对象a进行abs(a)处理时,调用对象a的内置方法__abs__
__hash__ hash(a)
__int__ int(a)
__long__ long(a)
__repr__ repr(a)

转载地址:http://cbbqj.baihongyu.com/

你可能感兴趣的文章
小甲鱼Python第十五讲(格式化)
查看>>
小甲鱼Python第十七讲(Python的乐高积木)
查看>>
小甲鱼Python第十八讲(函数:灵活即强大)
查看>>
小甲鱼Python第十九讲(函数,我的地盘听我的)
查看>>
小甲鱼python第二十讲(内嵌函数和闭包)
查看>>
小甲鱼Python第二十一讲(lambda表达式)
查看>>
小甲鱼Python第二十二讲(递归)
查看>>
小甲鱼Python第二十三讲、第二十四讲(递归-这帮小兔崽子、汉诺塔)
查看>>
小甲鱼Python第二十五讲、第二十六讲(字典)
查看>>
小甲鱼Python第二十七讲(集合)
查看>>
2020光学期刊一区二区影响因子发布(科睿唯安)
查看>>
可调谐半导体激光器的窄线宽测试及压缩
查看>>
matlab中 %d,%f,%c,%s
查看>>
常见的光纤接头汇总
查看>>
半导体激光器—问题整理(二)
查看>>
科研日记7.31
查看>>
问题整理3
查看>>
zemax仿真二向色镜
查看>>
stm32单片机编程时extern的用法
查看>>
UART4和5的问题
查看>>