当前位置: 首页 > article >正文

Python小白学习教程从入门到入坑------第二十五课 多态(语法进阶)

一、多态

含义:指同一种行为具有不同的表现形式

一个对象具有多种形态,在不同的使用环境中以不同的形态展示其功能,那我们就称该对象具有多态特征

eg:+ 号在不同的使用环境中,有着不同的功能

print(10+10)      # 算术运算符:可以实现整型之间的相加操作
print('10'+'10')  # 字符串拼接:实现字符串之间的拼接操作

1.1 多态的前提

前提:

1、继承

2、重写

多态的特点:

1. 不关注对象的类型,关注对象具有的行为,也就是对象的实例方法是否同名

2. 多态的好处可以增加代码的外部调用灵活度,让代码更加通用,兼容性比较强

3. 不同的子类对象,调用相同的父类方法,会产生不同的执行结果

eg:在子类中,同一种方法shout,有不同的表现形式

class Animal(object):
    """父类:动物类"""
    def shout(self):
        print("动物会叫")
class Cat(Animal):
    """子类一:猫类"""
    def shout(self):
        print("小猫喵喵喵")
class Dog(Animal):
    """子类二:狗类"""
    def shout(self):
        print("小狗汪汪汪")
cat = Cat()
cat.shout()
dog = Dog()
dog.shout()
# 输出内容:
# 小猫喵喵喵
# 小狗汪汪汪

1.2 多态性

多态性:一种调用方法,不同的执行结果

eg:test 函数传入不同的对象,执行不同对象的eat方法

class Animal(object):
    def eat(self):
        print("我会干饭")
class Pig(Animal):
    def eat(self):
        print("猪吃猪饲料")
class Dog(Animal):
    def eat(self):
        print("狗吃狗粮")
# 多态性:定义一个统一的接口,一个接口多种实现
def test(obj):   # 形参obj
    obj.eat()
animal = Animal()
pig = Pig()
dog = Dog()
test(animal)
test(pig)
test(dog)
# 输出内容:
# 我会干饭
# 猪吃猪饲料
# 狗吃狗粮

二、静态方法

使用@staticmethod 来进行修饰,静态方法没有self、cls(后面会讲到)参数的限制

注意:静态方法与类无关,可以被转换成函数使用

在静态方法中,取消了不必要的参数传递,有利于减少不必要的内存占用和性能消耗

2.1 基本格式

定义格式:

class 类名:
    @staticmethod
    def 方法名(形参):
        方法体

调用格式:

类名.方法名(实参)
对象名.方法名(实参)

2.2 静态方法实例 

eg1:静态方法既可以使用对象访问,也可以使用类访问

class Person(object):
    @staticmethod    # 静态方法
    def study():
        print("人类会学习")
# 静态方法既可以使用对象访问,也可以使用类访问
Person.study()  # 输出:人类会学习
pe = Person()
pe.study()      # 输出:人类会学习

eg2:静态方法中也可以传参

class Person(object):
    @staticmethod    # 静态方法
    def study(name):
        print(f"{name}会学习")
Person.study('junjun')  # 输出:junjun会学习
pe = Person()
pe.study('junjun')      # 输出:junjun会学习,调用方法时传参数

三、类方法

使用装饰器@classmethod 来标识为类方法,对于类方法,第一个参数必须是类对象,一般是以cls作为第一个参数

注意:

1、当方法中需要使用到类对象(如访问私有类属性等),定义类方法
2、类方法一般是配合类属性使用

定义格式:

class 类名:
    @classmethod
    def 方法名(cls,形参):
        方法体

eg:类方法内部可以访问类属性,或者调用其他的类方法

class Person(object):
    name = "junjun"
    @classmethod
    def sleep(cls):
        print("cls",cls)  # cls代表类对象本身,类本质上就是一个对象
        print("人类在睡觉")
        print(cls.name)
print(Person)
Person.sleep()
# 输出结果:
# <class '__main__.Person'>
# cls <class '__main__.Person'>
# 人类在睡觉
# junjun

四、总结

在类里面定义方法有三种:实例方法、静态方法、类方法

1.实例方法:方法内部访问实例属性,方法内部可以通过类名.类属性名来访问类属性

2.静态方法@staticmethod:方法内部,不需要访问实例属性和类属性,如果要访问类属性,通过类名.类属性名访问,不能访问实例属性

3.类方法@classmethod:方法内部只需要访问类属性,可以通过cls.类属性名访问类属性,不能访问实例属性

实例方法:

实例方法是绑定到类的实例上的方法。它们必须通过类的实例来调用,并且它们的第一个参数通常是self,指向调用该方法的实例本身。

eg:

class MyClass:  
    def instance_method(self):  
        print(f"这是一个实例方法,调用者是:{self}")  
  
# 创建类的实例  
obj = MyClass()  
# 调用实例方法  
obj.instance_method()  # 输出:这是一个实例方法,调用者是:<__main__.MyClass object at 0x...>

静态方法:

静态方法不依赖于类或实例,它们既不接收self也不接收cls作为第一个参数。它们通常用于在逻辑上属于类但不需要访问或修改类或实例状态的函数。静态方法使用@staticmethod装饰器来定义。

eg:

class MyClass:  
    @staticmethod  
    def static_method():  
        print("这是一个静态方法,不依赖于类或实例")  
  
# 直接通过类调用静态方法  
MyClass.static_method()  # 输出:这是一个静态方法,不依赖于类或实例  
# 也可以通过实例调用静态方法,但这不是必需的  
obj = MyClass()  
obj.static_method()  # 输出同上

类方法:

类方法绑定到类本身而不是类的实例。它们接收cls作为第一个参数,cls指向调用该方法的类本身。类方法使用@classmethod装饰器来定义,常用于创建或修改类级别的变量或执行类级别的操作。

eg:

class MyClass:  
    class_variable = 0  
  
    @classmethod  
    def class_method(cls):  
        print(f"这是一个类方法,调用者是:{cls}")  
        cls.class_variable += 1  
        print(f"类变量现在的值是:{cls.class_variable}")  
  
# 通过类调用类方法  
MyClass.class_method()  # 输出:这是一个类方法,调用者是:<class '__main__.MyClass'> 类变量现在的值是:1  
# 通过实例调用类方法,虽然不推荐,但也可以  
obj = MyClass()  
obj.class_method()  # 输出:这是一个类方法,调用者是:<class '__main__.MyClass'> 类变量现在的值是:2

联系:

1、所有的方法都可以访问类级别的属性(即类变量)

2、所有的方法都可以通过类名或实例名来调用(尽管对于实例方法和类方法,通过类名调用时需要传递实例或类本身作为第一个参数)

3、实例方法可以直接访问和修改实例属性,而静态方法和类方法则不能直接访问实例属性(除非通过其他方式传入)。

区别:

实例方法:第一个参数是self,必须通过实例调用

静态方法:无self或cls参数,可以通过类或实例调用,不依赖于类或实例

类方法:第一个参数是cls,代表类本身,可以通过类或实例调用

今天的分享就到这里了,希望能帮助到大家~


http://www.kler.cn/a/381195.html

相关文章:

  • 如何打造用户友好的维护页面:6个创意提升WordPress网站体验
  • shardingsphere分库分表项目实践1-让shardingsphere运行起来
  • 京东大数据治理探索与实践 | 京东零售技术实践
  • 利用.NET Upgrade Assitant对项目进行升级
  • 开发手札:CameraRTS精准性优化
  • 法学硕士,有哪些专业可以申请呢?
  • Vue.js 提供了一个事件系统,允许组件之间通过自定义事件进行通信
  • golang安装,常用框架安装,记忆点
  • ChatGPT o1与GPT-4o、Claude 3.5 Sonnet和Gemini 1.5 Pro的比较
  • 【Winform使用DataGridView实现表格数据的添加,编辑、删除、分页功能】
  • 【Go语言】| 第1课:Golang安装+环境配置+Goland下载
  • 基于Python的自然语言处理系列(50):Soft Prompt 实现
  • SAP 生产工单 bom组件 打删除标记
  • Spring Boot框架下的信息学科平台系统开发实战
  • SQL 常用更新操作
  • platform device的名字是怎么生成的?
  • 滑动窗口习题篇(下)
  • FreeRTOS学习8——开启任务调度器API函数简介
  • 【运维项目经历|046】Jenkins自动化部署与持续集成优化项目
  • MySQL秘密武器:索引与事务
  • 【51单片机】DS1302实时时钟
  • RabbitMQ最全教程-Part1(基础使用)
  • 活着就好20241106
  • 人脸检测之MTCNN算法网络结构
  • VUE+Vite之环境文件配置及使用环境变量
  • 全面解析:区块链技术及其应用