@classmethod
被修饰的方法成为一个类方法。
什么时候用@classmethod:1. 类内部定义了一个方法,默认传入self,但是self并没有被使用;2. 在这个方法中用到了当前的类名,或者准备使用这个类的内存空间中的名字
class Cir:
__pi = 3.14
def __init__(self,r):
self.r = r
self.area = __pi*self.r**2
# 正常我们对这么定义一个内部方法:
# def change_pi(self,new_pi):
# Cir.__pi = new_pi # 这里不能使用self.__pi,因为这样会创建一个新的私有变量
@classmethod # 把一个对象绑定的方法修改成一个类方法
def change_pi(cls,new_pi):
cls.__pi = new_pi # 这里相当于Cir.__pi = new_pi
使用@classmethod的好处:1. 在方法中仍然可以引用类中的静态变量;2. 可以不用实例化对象,直接用类名在外部调用这个方法。
@staticmethod
被修饰的方法成为一个静态方法。
# 当在类的内部定义一个不带self参数的普通函数时加上@staticmethod修饰器
class A:
def func():
print(666)
# 尝试执行func函数
A().func() # TypeError: func() takes 0 positional arguments but 1 was given
# 函数报错,因为类中的方法会默认传入self
# 所以需要加上@staticmethod
class A:
@staticmethod
def func():
print(666)
# 再次执行
A().func() # 666
# 加上这个修饰器后的函数内部既不会用到self变量也不会用到cls类
__new__
构造方法:创建一个实例化对象时,总是先创建一块对象的空间,有一个指针能指向类。这就是__new__
方法完成的工作。
class A:
def __new__(cls,*args,**kwargs):
ans = super().__new__(cls)
print(‘执行new‘,ans)
return ans
def __init__(self):
print(‘执行init‘,self)
# 观察创建一个实例化对象后的输出
A()
"""
执行new <__main__.A object at 0x0000021BF45F61C8>
执行init <__main__.A object at 0x0000021BF45F61C8>
"""
# 可以看到两个结果的地址完全相同
# 其实在实例化一个对象的时候,总是先执行__new__方法开辟空间
# 再执行__init__方法
__call__
带有__call__
方法 的类是可调用的(callable)。
# 当类中没有__call__方法时
class A:
pass
print(callable(A())) # False
# 当类中有__call__方法时
class B:
def __call__(self):
print(666)
print(callable(B())) # True
# 对象名+()默认调用类中的__call__方法
# 创建一个类的实例化对象
obj = B()
obj() # 666
__len__
对对象求长度时调用的方法。
class A:
def __init__(self):
self.li_1 = []
obj = A()
# 向列表添加元素
obj.li_1.append(1)
obj.li_1.append(2)
print(len(obj.li_1)) # 2
obj.li_1.append(3)
obj.li_1.append(4)
print(len(obj.li_1)) # 4
# 当向类中加入__len__方法后
class A:
def __init__(self):
self.li_1 = []
def __len__(self):
return len(self.li_1)
obj = A()
# 可以直接对对象求长度获得属性长度
obj.li_1.append(1)
obj.li_1.append(2)
print(len(obj)) # 2
obj.li_1.append(3)
obj.li_1.append(4)
print(len(obj)) # 4
__str__
当打印实例化对象时,如果类内部没有__str__
方法就输出对象所在的内存地址,有__str__
方法时直接输出__str__
方法return
的结果(但是这个方法只能返回str
类型的结果)。
# 当不定义__str__方法时
class People:
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
def __str__(self):
return ‘,‘.join([self.name,str(self.age),self.sex])
xiaoming = People(‘xiaoming‘,22,‘male‘)
xiaohong = People(‘xiaohong‘,21,‘female‘)
xiaohei = People(‘xiaohei‘,22,‘male‘)
print(xiaoming) # <__main__.People object at 0x0000021BF454D908>
# 输出结果是一个地址,内容不够直观
# 定义__str__方法后
class People:
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
def __str__(self):
return ‘,‘.join([self.name,str(self.age),self.sex])
xiaoming = People(‘xiaoming‘,22,‘male‘)
xiaohong = People(‘xiaohong‘,21,‘female‘)
xiaohei = People(‘xiaohei‘,22,‘male‘)
print(xiaoming) # xiaoming,22,male
# 直接输出结果,清晰明了
__repr__
当print
一个对象,用%s
进行字符串拼接或者str(对象)
时总是调用这个对象的__str__
方法,如果找不到__str__
方法则调用__repr__
方法;用%r
进行字符串拼接或者str(对象)
时总是调用这个对象的__repr__
方法。
原文:https://www.cnblogs.com/20-03-14/p/12628916.html