32.内置双下方法

内置的方法有很多,不一定全部都在object中,比如len(),数字无法计算长度,没有len()方法

__str__   

打印一个对象的时候,就是调用对象.__str__  用于对对象进行打印说明时

直接打印,%s,str()  这些实际调用的都是__str__,__str__的返回值必定是一个字符串

class A:
    def __str__(self):   #重写__str__方法
        return "'A's object"
a=A()
print(a)  #调用a.__str__

__repr__

%r 和repr ,实际上都是调用__repr__,__repr__的返回值必定是一个字符串

_repr__是__str__的备胎,在类中找不到__str__,就会再去寻找使用__repr__,找不到__repr__再去寻找父类的方法

class A:
    def __init__(self,name,money):
        self.name=name
        self.money=money
    def __repr__(self):
        return str(self.__dict__)
a=A('大黄',250)
print(repr(a))
print(a)          #这里本应该返回一个对象地址,因为找不到类中的__str__方法,实际上,__repr__是__str__的备胎,在类中找不到__str__,就会再去寻找使用__repr__
print('%r'%a)

__del__

析构函数:在删除一个对象之前,进行一些收尾工作,如关闭文件

执行函数del时,会先调用执行__del__,再删除变量

class A:
    def __del__(self):      
        print('执行我了')
a=A()
del a       #这里先执行定义的__del__方法里的程序,再将对象a删除
print(a)

执行结果:

执行我了

在程序执行完后,如果没有将对象删除,垃圾回收机制会自动调用__del__方法,删除程序中的变量和对象

验证代码如下:

class A:
    def __del__(self):
        print('执行我了')
a=A()
print(a)#程序没将对象a删除,因此代码结束后会调用__del__()来删除对象a

执行结果:

<__main__.A object at 0x000002245812B5F8>
执行我了

__call__

一个对象加上()相当于执行了__call__,如果类中没有定义__call__,就会报错

class A:
    def __call__(self):
        print('执行我了')
a=A()
a()   #执行__call__方法

执行结果:

执行我了

该函数可以用来打印对象的属性或给对象接收参数,代码如下:

class A:
    def __init__(self,name,money):
        self.name=name
        self.money=money
    def __call__(self,*args):
        print('执行我了')
        print(self.name)
        print(self.money)
        print(args[1])

a=A('sdd',23)
a(1,2,3)

可以通过定义__call__来定义对象名+()时的特定功能

item系列

__getitem__

想要以字典形式获取属性的值时,会自动调用__getitem__,即对象名['属性名']

如果类中没有定义__getitem__,只能以print(a.name)形式获取
class A:
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
def __getitem__(self, item):
print('hello')
return self.__dict__[item]
a=A('ass',12,'man')
print(a['name'])
#获取属性name的值,调用__getitem__,如果类中没有定义__getitem__,只能以print(a.name)形式获取

执行结果:

hello
ass

__setitem__

 以对象名['属性']=新值的形式来修改属性值时会调用该方法

如果没有该方法,就只能以对象名.属性名的形式修改

class A:
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex
    def __setitem__(self, item,value):
     print("修改属性值") self.
__dict__[item] = value a=A('ass',12,'man') a['name']='大黄' #如果没有__setitem__,就只能以a.name='大黄'的形式修改 print(a.__dict__)

执行结果:

修改属性值
{'name': '大黄', 'age': 12, 'sex': 'man'}

__delitem__

以del 对象名['属性']的形式删除属性

如果没有__delitem__,只能以del 对象名.属性名来删除属性

class A:
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex
    def __delitem__(self, key):
     print('删除属性')
del self.__dict__[key] a=A('ass',12,'man') del a['name'] #如果没有__delitem__,只能以del a.name来删除属性 print(a.__dict__)

执行结果:

删除属性
{'age': 12, 'sex': 'man'}

构造方法:

创建一个对象需要的方法

__new__(面试必考)  __init__

class A:
    def __init__(self):
        print('这里执行__init__')
    def __new__(cls, *args, **kwargs):
        print('这里执行__new__')
        return object.__new__(A,*args,**kwargs)  #new是无法实例化一个对象的,自己有object才能实例化一个对象

a=A()

执行结果:

这里执行__new__
这里执行__init__

设计模式:单例模式

一个类始终只有一个实类,单例模式的编码离不开__new__

当你第一次实例化这个类时,就创建一个实例化的对象;之后再来实例化的时候,就用之前创建的对象(想使用新的对象时,就将该对象的所有属性全部重新赋值属性,这样从头到尾就是在操作一个属性)

实现方法:

class A:
    __instance=False
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def __new__(cls, *args, **kwargs):
        if cls.__instance:   #非第一次实例化对象时,满足此条件,将上层实例化的对象直接返回
            return cls.__instance
        cls.__instance=object.__new__(A)     #第一次实例化对象时,执行此代码 ,将实例化的对象赋值给cls.__instance
        return cls.__instance    #将cls.__instance返回
a=A('大黄',23)
b=A('小黄',21)
print(a)
print(b)    #返回的是两个对象的地址,地址完全相同,是同一个对象
print(a.__dict__)   #返回的对象b的实现,表示对象a中的属性完全重新赋值
print(b.__dict__)

执行结果:

<__main__.A object at 0x000001A54854DCF8>
<__main__.A object at 0x000001A54854DCF8>
{'name': '小黄', 'age': 21}
{'name': '小黄', 'age': 21}

__eq__ 

执行==是就是在调用__eq__

__eq__默认比较地址,两个对象的地址不同,默认返回false
class A:
    def __init__(self,name):
        self.name=name
ob1=A('a')
ob2=A('a')
print(ob1==ob2)    #__eq__默认比较地址,两个对象的地址不同,默认返回false

执行结果:False

对__eq__进行修改,可以以设置根据什么来比较两者是否相同

class A:
    def __init__(self,name):
        self.name=name
    def __eq__(self, other):
        if self.name==other.name:    #定义__eq__方法,两者的name相同,就返回true
            return True
        else:
            return False
ob1=A('a')
ob2=A('a')
print(ob1==ob2)

执行结果:True

__hash__

执行hash()函数时,实际上就是在调用__hash__

只要是可hash的数,都在内部实现了__hash__

class A:
    def __init__(self,name,sex):
        self.name=name
        self.sex=sex
    def __hash__(self):
        return hash(self.name+self.sex)
a=A('a','man')
b=A('b','man')
print(hash(a))   #a在内部实现了__hash__,a也变成了可哈希数
print(hash(b))

执行结果:

1211493403233181463
-3611351746756962348

posted @ 2020-10-24 22:21  maday  阅读(66)  评论(0)    收藏  举报