面向对象编程之类方法@classmethod

面向对象编程之类方法@classmethod

首先还是我们熟悉的八股文

  • 类方法 就是针对 类对象 定义的方法

    • 类方法 内部可以直接访问 类属性 或者调用其他的 类方法

语法如下

@classmethod
def 类方法名(cls):
    pass
  • 类方法需要用 修饰器 @classmethod 来标识,告诉解释器这是一个类方法

  • 类方法的 第一个参数 应该是 cls

    • 哪一个类 调用的方法,方法内的 cls 就是 哪一个类的引用

    • 这个参数和 实例方法 的第一个参数是 self 类似

    • 提示 使用其他名称也可以,不过习惯使用 cls

  • 通过 类名. 调用 类方法调用方法时,不需要传递 cls 参数

在方法内部

  • 可以通过 cls. 访问类的属性

  • 也可以通过 cls. 调用其他的类方法

示例需求

  • 定义一个 工具类

  • 每件工具都有自己的 name

需求 —— 在 封装一个 show_tool_count 的类方法,输出使用当前这个类,创建的对象个数

@classmethod
def show_tool_count(cls):
    """显示工具对象的总数"""
    print("工具对象的总数 %d" % cls.count)

在类方法内部,可以直接使用 cls 访问 类属性 或者 调用类方法

类方法:通过@classmethod装饰器实现
类方法和普通方法的区别:
    类方法只能访问类变量,不能访问实例变量

直接看代码:

'''
类方法:通过@classmethod装饰器实现
类方法和普通方法的区别:
    类方法只能访问类变量,不能访问实例变量

(刨根问底)问题1:为什么类方法中不能够访问实例变量?
    答:因为类方法中的self并不是和创建的对象所绑定--简单点来说,因为self这个参数接收的不是实例本身,而是指向类本身

注:当你先写装饰器,在定义方法,会发现方法后的()内是cls 而不是self,这就印证了上面的说明!!

问题2:类方法到底有啥用?
'''
class Student:
    def __init__(self,name):
        self.name=name

    @classmethod
    def show(cls):
        print('学生的名字为:%s'%cls.name)


s1=Student('小明')
s1.show()

 

(刨根问底)问题1:为什么类方法中不能够访问实例变量?
    答:因为类方法中的self并不是和创建的对象所绑定--简单点来说,因为self这个参数接收的不是实例本身,而是指向类本身

class Student:
    name='dog1'
    def __init__(self,name):
        self.name=name

    @classmethod
    def show(self):
        print(self)
        print('学生的名字为:%s'%self.name)


s1=Student('小明')
s1.show()

你会发现类方法中的self指向的是类本身,而不是实例对象

class Student:
    name='dog1'
    def __init__(self,name):
        self.name=name

    @classmethod
    def show(self):
        print(self)
        print('学生的名字为:%s'%self.name)


s1=Student('小明')
s1.show()
print(Student)

注:当你先写装饰器,在定义方法,会发现方法后的()内是cls 而不是self,这就印证了上面的说明!!

class Student2:
    num=0
    def __init__(self,name):
        self.name=name
        self.num+=1
        print(self.name,self.num)

s2=Student2('小李')
s3=Student2('小红')

问题3:为什么num一直是1?

答:因为这里对num+1是针对的每个新创建的实例对象,而不是针对于整个大类而言

问题4:如何解决这个问题?

答:将Self换成类本身即可!!

class Student2:
    num=0
    def __init__(self,name):
        self.name=name
        Student2.num+=1
        print(self.name,self.num)

s2=Student2('小李')
s3=Student2('小红')

 但是这个代码有个bug!当你不创建对象,直接对在外部调用num时也可以使数量+1

class Student2:
    num=0
    def __init__(self,name):
        self.name=name
        Student2.num+=1
        print(self.name,self.num)

s2=Student2('小李')
s3=Student2('小红')
Student2.num+=1
print(Student2.num)

 

 问题5:如何解决这个问题?

答:可以使用类方法避免这个问题!

class Student2:
    #将num变成一个私有变量
    __num=0
    def __init__(self,name):
        self.name=name
        #Student2.num+=1
        Student2.gain_num()
        print(self.name,self.__num)

    @classmethod
    def gain_num(cls):
        cls.__num+=1

s2=Student2('小李')
s3=Student2('小红')
#Student2.num+=1
print(Student2.num)

 最终的代码如下:有小伙伴们找到bug可以和我交流一下!!

class Student2:
    #将num变成一个私有变量
    __num=0
    def __init__(self,name):
        self.name=name
        #Student2.num+=1
        Student2.__gain_num()
        print(self.name,self.__num)

    @classmethod
    def __gain_num(cls):
        cls.__num+=1

s2=Student2('小李')
s3=Student2('小红')

猜你喜欢

转载自blog.csdn.net/qq_46044325/article/details/127041159
今日推荐