day11 学习笔记

文章目录

  • 前言
  • 一、类方法
  • 二、静态方法
  • 三、构造方法
  • 四、魔术方法


前言

  • 通过今天的学习,我掌握了更多Python中有关面向对象编程思想中方法的概念与操作,包括类方法,静态方法,构造方法,魔术方法

一、类方法

类方法是属于类的行为,一般使用类而非对象进行调用

  • 类方法需要使用@classmethod装饰器定义
  • 类方法至少有一个形参用于绑定类,约定为cls
  • 类和该类的实例都可以调用类方法,但一般不用实例进行调用
  • 类方法不能访问此类创建的对象的实例属性
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)

二、静态方法

静态方法不依赖于类或者对象,一般封装了一些工具以供使用

  • 使用@staticmethod装饰器定义
  • 不需要self和cls参数
  • 通过类或类实例调用
  • 可以访问类属性,不能访问实例属性
class B:
	cnt = 0
	def f1(self):
		print("实例方法")
	@classmethod
	def f2(cls):
		print("类方法")
	@staticmethod
	def f3():
		print(math.pi ** 2)

三、构造方法

在Python中使用__new__作为构造方法,在创建实例时会自动调用

  • 负责对象的创建和内存分配。
  • 在对象实例化时被调用,负责返回一个新的对象实例。
  • 通常不需要显式地定义__new__()方法,Python会调用基类object的__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的对象

四、魔术方法

  • 魔术方法(自定义类的行为)
  • 魔术方法是一种特殊的方法,用双下划线包裹
  • 以便与内置Python功能(如+运算符、迭代、字符串表示等)交互
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

你可能感兴趣的:(学习,笔记,python)