Python-进阶特性篇(函数与OOP)

1、函数篇

定义:可以重复使用的一段代码

def 函数名(形参列表):
    //实现特定功能的多行代码
    [return [返回值]]
  • 函数名指向函数对象,传递函数->函数名,调用执行函数->函数名(实参)
  • 参数介绍
    • 顺序规则:必选 > 默认 > *args > 命名关键字 > **kw
参数类型 定义--形参 调用--实参
必选参数 func(name1, name2)

1、func(value1, value2)--按位置顺序传递值

2、func(name1=value, name2=value)--按参数名传递值

默认参数 func(name1 = value1, name2 = value2) 1、func()--没有传入实参,使用形参默认值
可变参数-位置参数 func(*args)

1、func(value1, value2)--args[0]为value1,args[1]为value2

2、接受任意个实参

可变参数-关键字参数 func(**kw)

1、func(name1 = value1, name2 = value2)

2、kw[name1] = value1

3、接受任意个键值对实参

万能参数 func(*args, **kw)

1、接受任意的实参,包括普通实参和键值对实参

  • 返回值
    • return 返回值:返回多个值时,实际上返回的是一个元组
    • 没有return:返回None
  • 匿名函数:方便用来表示仅包含1个表达式的函数
函数名 = lambda [形参列表]:expression
1、只能有1个表达式(常用于sort()、filter()等高阶函数)
2、表达式的结果就是返回值
  • LEGB 规则:查找变量时遵循的优先级顺序,Local(局部) -> Enclosing(嵌套) -> Global(全局) -> Built-in(内置)

    • Local(局部作用域):当前函数(或代码块)内部定义的变量。
    • Enclosing(嵌套作用域):嵌套函数(闭包)的外层函数作用域。
      • 内层函数可以访问外层函数的变量,但外层函数不能访问内层函数的变量。
      • 逐层向外查找,找到即停止。
      • 内层函数中修改外层(非全局)函数的变量:必须使用 nonlocal 关键字
    • Global(全局作用域):当前模块(.py 文件)的顶层(全局)定义的变量。
      • 函数内部读取全局变量:直接读取即可
      • 函数内部修改全局变量:必须使用 global 关键字声明
    • Built-in(内置作用域):Python解释器内置的变量和函数

2、类和对象篇

  • 类(Class):是创建对象的蓝图或模板。它定义了一组属性(数据,用变量表示)和方法(行为,用函数表示)。

    • 类本身是一个逻辑上的抽象概念,例如“人类”定义了所有人类共有的特征和行为。

  • 对象(Object):是根据类这个模板创建出来的具体实体(即实例)。

    • 它拥有类所定义的属性和方法,但每个对象的属性值可以是独立的(例如,一个苹果是红的,另一个苹果可能是绿的)。对象在程序运行时存在于内存中。

    • 构造方法(Constructor):类中一种特殊的方法,在实例化时被自动调用,用于初始化新创建对象的状态或属性。

    • 实例化(Instantiation):以类为模板,在内存中“生产”出一个新对象的过程。

    • cls:类方法的第一个参数,指向类本身
    • self:实例方法的第一个参数,指向实例对象本身
    • super():返回一个代理对象,用于在继承关系中按照方法解析顺序(MRO) 自动查找并调用下一个类的方法。(访问父类方法)
      • 关键作用:解决多继承中的方法调用冲突,确保父类方法被正确调用。
      • super(B, self):表示从B类在MRO顺序中的下一个类开始查找方法。self则提供了实例上下文。
      • MRO(方法解析顺序):Python计算出的一个类继承顺序列表(可通过类名.__mro__查看),super()严格按照此顺序进行方法查找。
class A:
    def show(self): print("A")
class B(A):
    def show(self):
        super().show()  # 调用MRO中B的下一个类(即A)的show
        print("B")
print(B.__mro__) #(<class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
b = B()
b.show() #先打印A,再打印B
class 类名(父类1,父类2):
    多个属性...
    多个方法...
  • 元类、metaclass:控制类的创建(可以指定metaclass改变类的生成方式--仅做了解)
    • 创建对象:instance_demo = 类名()
    • 枚举类:对象个数固定的类(周末类、月份类),需要继承Enum
  • 类的成员:属性+方法
  • 属性介绍
    • 类属性:类内部、方法之外定义的变量
    • 实例属性:方法内部,使用"self.变量名"定义的变量
    • 局部属性:方法内部,以"变量名=变量值"定义的变量
    • 特殊属性
      • __doc__:类的描述信息\类前面的注释
      • __class__:类的类型、比如<class '__main__.b'>
      • __name__:类名、对象名
  • 实例方法、类方法(@classmethod)、静态方法(@staticmethod)
实例方法 def study(self):
  print(self,"正在学Python")

Python解释器使用self判断调用方法的是哪个对象

1、第一个参数必须是self,它代表调用该方法的具体实例对象

2、通过self,可以自由访问和修改该实例的属性,也可以通过self.__class__访问类的属性。

3、访问:instance_demo.study()

4、使用场景:几乎所有需要处理对象特有数据的操作,都应该定义为实例方法。

静态方法

@staticmethod

def study():
  print("正在学Python")

1、本质上就是一个放在类里的普通函数

2、不能直接访问实例属性或类属性

3、使用场景:一个独立的工具函数

类方法

@classmethod

def study(cls):
  print("正在学Python")

1、使用@classmethod装饰,第一个参数必须是cls,它代表类本身

2、通过cls,可以访问和修改类属性,但不能访问任何实例属性(因为没有self)。

3、使用场景:工厂方法+操作类属性

    # 工厂方法
    @classmethod
    def from_string(cls, desc):
        # 假设描述是 "name:旺财"
        name = desc.split(":")[1]
        return cls(name)  # 创建并返回不同的实例

 

  • 常用特殊方法(魔术方法)
    • 以下这些以双下划线开头和结尾的特殊方法,用于在特定操作发生时(如对象被调用、属性被访问时)自动触发,可以让我们自定义对象的行为。
构造方法  

def __new__(self,...):

  代码块

创建并返回对象
初始化方法

def __init__(self,...):

  代码块

对生成的对象进行初始化

 call方法

def __call__(self,...):

  代码块

1、instance_demo():调用对象时,访问__call__()

class Demo:
    def __call__(self):
        print("对象被调用了!")
    def __getattr__(self, name):
        return f"你访问的属性 '{name}' 不存在"
额外属性方法

def __getattr__(self,...):

  代码块

1、instance_demo.other_attr:访问的属性不存在时,访问 __getattr__()
 字符串方法

def __str__(self,...):

  代码块

1、print(instance_demo):打印对象时,访问__str__()

2、默认的__str__()还会访问__repr__()

3、__repr__():返回对象信息

比如<__main__.B object at 0x0000029B0BEB22B0>

 

  • 三大特征:封装、继承、多态
封装

将类的某些信息隐藏在类内部,不允许外部程序直接访问,只能通过该类提供的方法来访问

  • @property装饰器:将方法变为属性调用  
# 将get_name和set_name方法变成属性调用

class Person:
    def __init__(self, name):
        self._name = name
    @property
    def name(self):
        return self._name
    @name.setter
    def name(self, value):
        self._name = value

1、将name定义为私有

2、定义方法访问name

def set_name(self,name):
  self.name = name
def get_name(self):
  return self.name

继承

在已存在类的基础上进行扩展产生新类

1、子类拥有父类的所有成员

2、子类可以重写父类方法

--访问父类被重写的方法:父类.方法名(子类对象)

class 类名(父类1, 父类2, ...):

   #类定义部分

多态

 相同方法在父类及其各个子类中具有不同的实现

# 1. 定义父类 Animal
class Animal:
    def __init__(self, name):
        self.name = name

    # 父类中定义了一个通用方法 speak,但暂时没有具体实现
    def speak(self):
        # 可以抛出一个异常,提醒子类必须重写此方法
        raise NotImplementedError("子类必须实现 speak 方法")

# 2. 定义不同的子类,并重写父类的 speak 方法
class Dog(Animal):
    def speak(self):
        # 子类提供了自己的具体实现
        return f"{self.name} 汪汪叫!"

class Cat(Animal):
    def speak(self):
        return f"{self.name} 喵喵叫!"

# 3. 定义一个“接口”函数,它接收任何 Animal 类型的对象
def make_animal_speak(animal):
    # 注意:这里我们只关心对象有没有 speak 方法,而不关心它具体是什么类型
    print(animal.speak())

# 4. 创建不同的动物实例
dog = Dog("旺财")
cat = Cat("咪咪")

# 5. 调用同一个函数,传入不同的对象,表现出不同的行为 —— 这就是多态!
make_animal_speak(dog)   # 输出:旺财 汪汪叫!
make_animal_speak(cat)   # 输出:咪咪 喵喵叫!

1、前提:继承+子类重写父类方法

2、使用不同子类对象,可访问不同的实现

3、程序运行时根据传入的实际对象类型(Dog还是Cat),

4、自动找到并执行对应类中重写的speak方法

posted @ 2026-07-03 14:29  Fēngwèi  阅读(5)  评论(0)    收藏  举报