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!
类的定义、和使用就到这里了;下一章将会讲一下面向对象的三大特性,封装、 继承和多态

浙公网安备 33010602011771号