Python游戏世界打怪升级之新手指引十二【类】

今天我们一起来学下Python的类,再学习类的之前,我们首先要明白下面知识点

  • 命名空间
  • 作用域
  • global、nonlocal

命名空间

是一个从名称到对象的映射,Python中的每一个模块、函数、类都有自己的命名空间,用于存储变量、函数、类的名称。命名空间在不同时刻创建的,且拥有不同的生命周期。

分为以下几种类型

  • 内置命名空间,在Python解释器启动时候创建,退出时候销毁
  • 局部命名空间,在函数或者方法调用时候创建,调用结束销毁
  • 全局命名空间,在模块加载时候创建,模块卸载时候销毁

作用域

作用域是命名空间在程序中的可见范围,从内到外分为以下几种

  • 局部作用域Local Scope

    • 函数、方法内部的变量
    • 只在函数、方法内部可见
  • 嵌套作用域Enclosing Scope

    • 闭包函数的外部函数作用域
    • 用于嵌套函数中访问外部函数的变量
  • 全局作用域Global Scope

    • 模块级别的变量
    • 在整个模块中可见
  • 内置作用域Built-in Scope

    • Python内置的函数、对象
    • 在整个程序中可见

作用域规则

Python在查找变量时候,按照Local、Enclosing、Global、Built-in的顺序依次查找

global、nonlocal

  • global语句用于表面特定变量在全局作用域里面,并在全局作用域中重新绑定
  • nonlocal语句表示特定变量在外层作用域中,并在外层作用域中重新绑定

下面来进行例子演示,如何引用不同的作用域、命名空间;以及global、nonlocal对变量的影响

# global,用于在函数或其他局部作用域中声明一个变量为全局变量。
# 通过使用 global,可以在局部作用域中修改全局作用域中的变量
# 如果全局变量和局部变量同名,局部变量会遮蔽全局变量。
# 如果需要访问全局变量,必须使用 global

spam = "test spam"

def do_global():
    global spam
    print(spam) # test spam
    spam = 'global spam'
    print(spam) # # global spam

do_global()
print(spam) # global spam



# nonlocal用于在 嵌套函数 中声明一个变量为 外层函数(非全局)的变量。
# 通过使用 nonlocal,可以在内层函数中修改外层函数的变量

def outer():
    x = 10  # 外层函数的变量

    def inner():
        nonlocal x  # 声明 x 是外层函数的变量
        x = 20      # 修改外层函数的变量

    inner()
    print("Outer x:", x)  # 输出: 20

outer()

下面来看一下他们两个一起使用的综合例子

# 综合例子
def scope_test():
    def do_local():
        spam = "local spam"

    def do_nonlocal():
        nonlocal spam
        spam = "nonlocal spam"

    def do_global():
        global spam
        spam = "global spam"

    spam = "test spam"
    do_local()  # 这个spam作用域是局部变量,只存在do_local,不会影响scope_test的spam
    print("After local assignment:", spam)  # test spam
    do_nonlocal()  # 这个spam使用了nonlocal,修改scope_test的变量spam
    print("After nonlocal assignment:", spam)  # nonlocal spam
    do_global()  # 这个spam虽然使用了global,声明全局变量;而不是外层函数 scope_test 中的 spam;
    print("After global assignment:", spam)  # nonlocal spam,scope_test的变量spam已经被上面的do_nonlocal修改了


scope_test()  # 因为这个里面有do_global,里面使用了global,所以影响到了下面的spam输出
print("In global scope:", spam)  # global spam

"""
After local assignment: test spam
After nonlocal assignment: nonlocal spam
After global assignment: nonlocal spam
In global scope: global spam
"""

通过上面的例子也了解了命名空间的生命周期,以及作用域;下面就让我们进入到类的学习里去吧,主要学习下面几种

  • 类的定义
    • __init__方法,构造函数,初始化实例变量
    • 类变量,所有实例共享
    • 实例变量,每一个实例所独有
  • 类的操作
    • 创建实例
    • 访问属性,类中通过实例访问的变量就是属性
    • 调用方法,类中的函数就是方法
  • 给属性指定默认值
  • 修改属性的值
    • 直接修改
    • 通过方法修改
    • 通过方法让属性的值递增
class Car:
    # 类变量(所有实例共享)
    wheels = 4  # 所有汽车都有 4 个轮子

    def __init__(self, make, model, year):
        # 实例变量(每个实例独有)
        self.make = make  # 品牌
        self.model = model  # 型号
        self.year = year  # 年份
        self.odometer_reading = 100  # 里程数,默认值为 100 ;给属性默认值

    # 方法:描述汽车
    def describe_car(self):
        return f"{self.year} {self.make} {self.model}"

    # 方法:读取里程数
    def read_odometer(self):
        return f"This car has {self.odometer_reading} miles on it."

    # 方法:直接修改里程数
    def update_odometer(self, mileage):
        if mileage >= self.odometer_reading:
            self.odometer_reading = mileage
        else:
            print("You can't roll back an odometer!")

    # 方法:递增里程数
    def increment_odometer(self, miles):
        if miles > 0:
            self.odometer_reading += miles
        else:
            print("You can't add negative miles!")


# 创建实例
my_car = Car("Toyota", "Corolla", 2022)

# 调用方法
print(my_car.describe_car())  # 输出: 2022 Toyota Corolla

# 访问属性
print("Number of wheels:", my_car.wheels)  # 输出: Number of wheels: 4

# 访问默认属性值
print(my_car.read_odometer())  # 输出: This car has 0 miles on it.

# 直接修改属性值
my_car.odometer_reading = 100
print(my_car.read_odometer())  # 输出: This car has 100 miles on it.

# 通过方法修改属性值
my_car.update_odometer(200)
print(my_car.read_odometer())  # 输出: This car has 200 miles on it.

# 尝试回滚里程数(不允许)
my_car.update_odometer(150)  # 输出: You can't roll back an odometer!

# 通过方法递增属性值
my_car.increment_odometer(50)
print(my_car.read_odometer())  # 输出: This car has 250 miles on it.

# 尝试增加负里程数(不允许)
my_car.increment_odometer(-10)  # 输出: You can't add negative miles!

类的定义、和使用就到这里了;下一章将会讲一下面向对象的三大特性,封装、 继承和多态

posted @ 2025-03-20 12:47  小鑫仔  阅读(21)  评论(0)    收藏  举报