python 内置方法(进阶,重要)

一. 内置方法,进阶
双下方法:
内置函数/特殊语法/语法糖/内置的模块
1. __call__ 相当于 对象()调用__call__方法 [flask (django)]
A()() # 类名()(), 调用__call__方法
相当于先实例化得到一个对象,在对对象(),==>和上面的结果一样, 相当于调用__call__方法
2. __new__ 特别重要 开辟内存空间的 类的构造方法 有return
1. 开辟一个空间,属于对象的 obj = object.__new__(cls) # 创建一个空间(内存地址)
2. 把对象的空间传给self,执行init
3. 将这个对象的空间返回给调用者


3. __len__ len(obj) 调用了 __len__这个方法 有return
内置函数和类的内置方法是有联系的
len(obj)相当于调用了这个obj的__len__方法
__len__方法return的值就是len函数的返回值
如果一个obj对象没有__len__方法,那么len函数会报错
4. __str__ str(obj), '%s' % obj, print(obj) 有return
print一个对象相当于调用一个对象的__str__方法
内置的数据类型,内置的类,相当于执行__str__ print(str(对象))
__str__: str(obj), 要求obj必须实现了__str__, 要求这个方法的返回值必须是字符串str类型
print % s


5. __init__ 特殊语法 初始化方法,在实例化的时候__new__之后调用


6. __repr__ : 是 __str__的备胎,如果有__str__方法,那么 print %s str
都先执行__str__方法,并且使用__str__返回值
如果没有__str__,那么 print %s str都会执行repr
repr(obj),%r

在子类中使用__str__,先找子类的__str__,没有的话要向上找,只要父类不是object,就执行父类的__str__
但是如果除了object之外的父类都没有__str__,就执行子类的__repr__,如果子类也没有,还要
向上继续找父类的__repr__方法.
一直找不到,就打印某某对象的内存地址
__repr__,__str__
__repr__ repr %r
__str__ print %s str
如果没有str,所有原本要调用__str__方法的语法,都会调用__repr__
反过来如果没有repr,会使用父类的repr,str不能替代
在继承中: 如果子类没有str,会先到父类找str,再找子类的repr - 扩展



所有的双下方法, 没有 需要你在外部直接调用的
而是总有一些其他的 内置函数 特殊的语法 来自动触发这些 双下方法




1. __call__ 方法
class Apple():

    def __call__(self, *args, **kwargs):
        print('__call__方法 ...')

class Banana(Apple):
     def __init__(self,call):
        self.call = call()  # 这里相当于一个类的实例化对象
        self.call()     # 通过self.call(是一个对象)是拿到一个类的实例化 再加(),就是执行__call__方法

A = Apple()
A() # 对象A加 () 执行__call__方法,或者类名Apple加()()也是执行__call__方法

B = Banana(Apple)   # 传一个类名
 
 

2. __new__和__init__方法

class Apple:
    def __new__(cls, *args, **kwargs):  # 在执行new根本没有创建空间,只能转类的空间
        obj = object.__new__(cls)          # 对象的地址  self,obj
        print("在new方法里",obj)
        return obj

    def __init__(self):
        print("在init方法里",self)


obj = Apple()
print(obj)


# 单例类(比较重要)
# 如果这个类,从头到尾只能有一个实例,那么这个类就是一个单例类
class Apple:
    __apple = None
    def __new__(cls, *args, **kwargs):
        if not cls.__apple:        # 判断是否存在
            cls.__apple = object.__new__(cls)  # 对象地址
        return cls.__apple
    def __init__(self):
        pass

a1 = Apple()
a2 = Apple()
print(a1)
print(a2)

# 解释: 通过一次Apple()的实例化对象a1, 执行 __new__方法,
# 判断cls.__apple == None:, 所以就是不存在,就执行下面的
# 代码,把a1的对象地址,通过__new__方法传给cls.__apple,
# 所以cls.__apple,就拿到了a1的对象地址,cls.__apple == a1
# 第二次实例化对象a2, 执行__new__方法,判断存在cls.__apple它,
# 是一个a1的对象地址,所以就不执行if里面的内容,直接把a1的对象
# 地址返回给了a2,所以 a2 = a1 ,的内存地址,就是一个单例类.

# 总的来说就是开头设置一个不存的属性,把第一次的对象地址通过判断
# 传给它,在把对象地址返回给原来的对象,实例化第二次的时候,发现
# 通过判断哪个属性存在值了,就不去执行了,返回哪个存在的值(就是
# 第一次实例化对象的地址)给第二次的对象,

3. __len__和__iter__方法

class Len:
    def __init__(self):
        pass
    def __len__(self):
        print("执行__len__了")
        return len(self.__dict__)      # 返回的是对象属性的多少  len意思是长度
    def __iter__(self):
        print('执行__iter__方法...')
        return len(self.__dict__)

a = Len()
len(a)   # len(对象)  执行len这个方法
print(len(a))   # 调用了__len__方法,和接收返回值
# len(obj)相当于调用了这个obj的__len__方法
# __len__方法return的值就是len函数的返回值
# 如果一个obj对象没有__len__方法,那么len函数会报错

a.__iter__()    # 相当于调用了__iter__方法
print(a.__iter__()) # 调用了__iter__方法,和接收返回值





















猜你喜欢

转载自www.cnblogs.com/Pengdachui-1/p/11938559.html