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

Posted on 2019-11-27 11:55  S-skill  阅读(210)  评论(0编辑  收藏  举报
一. 内置方法,进阶
双下方法:
内置函数/特殊语法/语法糖/内置的模块
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__方法,和接收返回值

 

4. __str__和__repr__方法

class Apple:
    def __str__(self):
        return "%s %s %s" % (self.school,self.classmate,self.name)

    def __init__(self,school,classmate,name):
        self.school = school
        self.classmate = classmate
        self.name = name

a = Apple("XXXX","X",18)
print(a)       # 相当于执行了__str__方法
print(str(a))    # 内置的数据类型,内置的类,相当于执行__str__





class Apple:
    def __init__(self,school):
        self.school = school

    def __str__(self):      # 先找__str__方法打印,然后再找__repr__方法
        return "Apple %s __str__..." % self.school

    def __repr__(self):
        return 'Apple __repr__...'

class Banana(Apple):

    def __str__(self):      # 先找本类的__str__方法打印,然后再到父类找__str__方法,没有的话,找__repr__方法替代
        return "Banana %s __str__..." % self.school

    def __repr__(self):
        return "Banana  __repr__..."

a = Banana("苹果")
print(a)    # 执行 __str__方法,如果没有__str__方法会找__repr__方法去执行
print(str(a),repr(a))   # 如果没有__repr__方法,会打印出对象的地址
print("%s | %r" % (a,a))

 









Copyright © 2024 S-skill
Powered by .NET 8.0 on Kubernetes