类方法是属于类的行为,一般使用类而非对象进行调用
class A:
x = 100
def __init__(self,y):
self.y = y
def f1(self): #实例方法
print(self.x)
@classmethod #类方法,不创建对象也可以直接调用
def f2(cls): #cls相当于类本身
print(cls,cls.x)
a = A(200)
print(a.x)
print(a.f1())
print(a.f2()) #对象也能调用类方法,但不建议使用
print(A.f2())
print(A.f1(A)) #类可以调用成员方法,但需要手动传参
tips:使用实例调用类方法传入的参数仍然是实例所属的类,因此我们一般让实例调用实例方法而类调用类方法
以下展示使用类方法创建单例:
class Single:
instance = None
@classmethod
def share_instance(cls):
if cls.instance == None:
cls.instance = cls()
return cls.instance #返回一个对象
else:
return cls.instance
s1 = Single.share_instance()
s2 = Single.share_instance()
print(id(s1),id(s2)) #实际值创建了一个对象
# 多例
s1 = Single()
s2 = Single()
print(id(s1),id(s2)) #创建两个不同的对象
以下展示通过类方法一次性创建多个对象:
class Student:
def __init__(self,name=None,age=0):
self.name = name
self.age = age
@classmethod
def creat_stu(cls,num):
arr = []
for i in range(num):
arr.append(cls())
return arr
arr = Student.creat_stu(20)
静态方法不依赖于类或者对象,一般封装了一些工具以供使用
class B:
cnt = 0
def f1(self):
print("实例方法")
@classmethod
def f2(cls):
print("类方法")
@staticmethod
def f3():
print(math.pi ** 2)
在Python中使用__new__作为构造方法,在创建实例时会自动调用
class M:
pass
class Myclass:
def __new__(cls):
print("调用__new__方法,创建对象")
return M()
def __init__(self):#__init__方法是在__new__方法返回当前类的实例后才会被调用
print("调用__init__方法,初始化对象")
a = Myclass()
print(type(a)) #
tips:这里展示的是一种自定义情况,在默认情况下Python会调用基类的构造方法创建对象返回当前类的对象,接着__init__接收该对象并初始化。
而在这里自定义了__new__的返回值是M类,__init_不再执行,创建的对象也是M类而非Myclass的对象
class Person:
#初始化对象属性
def __init__(self,name,age):
self.name = name
self.age = age
#定义对象的字符串表示形式,使用print或str函数时自动调用
def __str__(self):
return "person"
#定义对象的“官方”字符串表示形式
def __repr__(self):
return "Python"
#定义对象相加的行为,使对象可以使用`+`运算符相加
def __add__(self,other):
return self.age + other.age
#定义对象相减的行为,使对象可以使用`-`运算符相减
def __sub__(self,other):
return self.age - other.age
#定义对象小于其他对象的行为,使对象可以使用`<`运算符比较
def __lt__(self,other):
return self.age < other
#定义对象大于其他对象的行为,使对象可以使用`>`运算符比较
def __gt__(self,other):
return self.age > other
#定义对象相等性的行为,使对象可以使用`==`运算符比较
def __eq__(self, value):
return self.age == value
p1 = Person("xiaohu",20)
p2 = Person("xiaozahng",22)
print(p1)
print(str(p1))
print(repr(p1))
print(p1+p2)
print(p1-p2)
print(p1<100)
print(p1>0)
print(p1==20)
tips:利用以上展示的魔术方法,我们可以使用Python的运算符根据我们自定义的方法直接运算对象,大大提高了代码的灵活性
以下展示一些常用的魔术方法:
class Image:
arr = [1.jpg,2.jpg]
def __init__(self,path):
self.path = path
#自定义获取长度
def __len__(self):
return len(self.arr)
#自定义取值
def __getitem__(self,index):
return self.arr[index]
#自定义存值
def __setitem__(self,index,value):
return self.arr[index] = value
#将对象作为函数
def __call__(self,*args,**kargs):
print("callable",*args,**kargs)
im = Image("...")
print(len(im))
print(im[0])
im[o] = "3.jpg"
print(im[0])#自定义后存取值操作,此时im[0]会变化
callable(im)#True