Python 类
类
Python 支持面向对象编程(OOP),允许开发者使用类和对象来组织和管理代码。类是创建对象的蓝图,通过类可以封装数据和功能,促进代码的复用性和可维护性。
名称和对象
在 Python 中,一切皆对象。类本身也是对象,具有自己的属性和方法。每个对象都有一个唯一的身份(ID)、类型(type)和一个值(value)。
- 名称:名称是指向对象的引用,类似于变量名。名称绑定到对象,而不是对象绑定到名称。
- 对象:对象是类的实例,拥有类定义的属性和方法。
示例:
class Dog:passmy_dog = Dog()
print(type(my_dog)) # 输出: <class '__main__.Dog'>
Python 作用域和命名空间
作用域(Scope)和命名空间(Namespace)是理解变量解析和访问权限的关键概念。
作用域和命名空间示例
- 局部作用域:函数或方法内部定义的命名空间。
- 全局作用域:模块级别的命名空间。
- 内建作用域:Python 解释器启动时创建的命名空间,包含内置函数和异常。
示例:
x = "全局变量"def foo():x = "局部变量"print(x)foo() # 输出: 局部变量
print(x) # 输出: 全局变量
初探类
类是创建对象的蓝图,定义了对象的属性和行为。通过类,可以创建多个实例,每个实例都有自己的属性值。
类定义语法
使用 class
关键字定义类,类名通常采用大驼峰命名法。
示例:
class Dog:"""一个简单的狗类"""def __init__(self, name, age):"""初始化属性"""self.name = nameself.age = agedef sit(self):"""模拟小狗被命令时蹲下"""print(f"{self.name} is now sitting.")def roll_over(self):"""模拟小狗被命令时打滚"""print(f"{self.name} rolled over!")
Class 对象
类本身也是对象,属于 type
类型。可以动态地为类添加属性和方法。
示例:
class MyClass:passprint(type(MyClass)) # 输出: <class 'type'># 动态添加属性
MyClass.attr = "类属性"
print(MyClass.attr) # 输出: 类属性
实例对象
实例对象是根据类创建的具体对象,拥有类定义的属性和方法。
示例:
my_dog = Dog('Willie', 6)
print(f"My dog's name is {my_dog.name}.") # 输出: My dog's name is Willie.
print(f"My dog is {my_dog.age} years old.") # 输出: My dog is 6 years old.
my_dog.sit() # 输出: Willie is now sitting.
方法对象
方法是类中的函数,定义了对象的行为。方法的第一个参数通常为 self
,代表实例本身。
示例:
class Cat:def __init__(self, name):self.name = namedef meow(self):print(f"{self.name} says Meow!")my_cat = Cat('Whiskers')
my_cat.meow() # 输出: Whiskers says Meow!
类和实例变量
- 类变量:属于类本身,所有实例共享。定义在类体中,但不在任何方法内。
- 实例变量:属于每个实例,互不影响。通常在
__init__
方法中通过self
定义。
示例:
class Bird:species = '鸟类' # 类变量def __init__(self, name):self.name = name # 实例变量bird1 = Bird('Sparrow')
bird2 = Bird('Eagle')print(bird1.species) # 输出: 鸟类
print(bird2.species) # 输出: 鸟类bird1.species = '麻雀' # 修改实例变量,不影响类变量
print(bird1.species) # 输出: 麻雀
print(bird2.species) # 输出: 鸟类
print(Bird.species) # 输出: 鸟类
补充说明
特殊方法
类中可以定义特殊方法(如 __init__
, __str__
, __repr__
等)来定制对象的行为。这些方法以双下划线开头和结尾,具有特定的用途。
示例:
class Point:def __init__(self, x, y):self.x = xself.y = ydef __str__(self):return f"Point({self.x}, {self.y})"def __repr__(self):return f"Point(x={self.x}, y={self.y})"p = Point(1, 2)
print(p) # 输出: Point(1, 2)
print(repr(p)) # 输出: Point(x=1, y=2)
描述符
描述符是实现了 __get__
, __set__
, __delete__
方法的类,用于管理属性访问。
示例:
class Descriptor:def __init__(self):self.value = Nonedef __get__(self, obj, objtype):return self.valuedef __set__(self, obj, value):if not isinstance(value, int):raise ValueError("必须是整数")self.value = valuedef __delete__(self, obj):del self.valueclass MyClass:attr = Descriptor()instance = MyClass()
instance.attr = 10
print(instance.attr) # 输出: 10
# instance.attr = "Hello" # 将引发 ValueError: 必须是整数
属性(Properties)
使用 @property
装饰器将方法转换为属性,实现属性的获取、设置和删除操作,增强封装性。
示例:
class Temperature:def __init__(self, kelvin):self._kelvin = kelvin@propertydef kelvin(self):return self._kelvin@kelvin.setterdef kelvin(self, value):if value < 0:raise ValueError("温度不能低于绝对零度")self._kelvin = value@kelvin.deleterdef kelvin(self):del self._kelvintemp = Temperature(300)
print(temp.kelvin) # 输出: 300temp.kelvin = 310
print(temp.kelvin) # 输出: 310# temp.kelvin = -5 # 将引发 ValueError: 温度不能低于绝对零度
继承
继承是面向对象编程的核心概念之一,允许子类继承父类的属性和方法,实现代码复用和扩展。
多重继承
一个子类可以继承多个父类,形成多重继承关系。Python 使用方法解析顺序(MRO)来确定方法和属性的搜索顺序。
示例:
class Mother:def skills(self):print("Cooking")class Father:def skills(self):print("Driving")class Child(Mother, Father):def skills(self):Mother.skills(self)Father.skills(self)print("Programming")child = Child()
child.skills()
# 输出:
# Cooking
# Driving
# Programming
私有变量
通过命名约定控制属性和方法的访问权限,增强封装性和数据保护。
命名约定
- 单前导下划线
_
:表示受保护的属性或方法,建议内部使用,外部不直接访问。 - 双前导下划线
__
:触发名称重整(Name Mangling),使属性在类外部难以访问。
示例:
class MyClass:def __init__(self):self.public = "公开属性"self._protected = "受保护属性"self.__private = "私有属性"def public_method(self):print("公开方法")def _protected_method(self):print("受保护方法")def __private_method(self):print("私有方法")obj = MyClass()
print(obj.public) # 输出: 公开属性
print(obj._protected) # 输出: 受保护属性
# print(obj.__private) # 将引发 AttributeErrorobj.public_method() # 输出: 公开方法
obj._protected_method() # 输出: 受保护方法
# obj.__private_method() # 将引发 AttributeError# 通过名称重整访问私有属性(不推荐)
print(obj._MyClass__private) # 输出: 私有属性
obj._MyClass__private_method() # 输出: 私有方法
使用 property
控制访问
通过 @property
装饰器和相应的装饰器控制属性的访问和修改,提供更好的封装。
示例:
class BankAccount:def __init__(self, balance=0):self._balance = balance@propertydef balance(self):return self._balance@balance.setterdef balance(self, amount):if amount < 0:raise ValueError("余额不能为负数")self._balance = amount@balance.deleterdef balance(self):del self._balanceaccount = BankAccount(100)
print(account.balance) # 输出: 100account.balance = 150
print(account.balance) # 输出: 150# account.balance = -50 # 将引发 ValueError: 余额不能为负数
杂项说明
方法装饰器
除了 @property
,还有其他方法装饰器如 @classmethod
和 @staticmethod
,用于定义类方法和静态方法。
示例:
class MyClass:@classmethoddef class_method(cls):print("这是一个类方法")@staticmethoddef static_method():print("这是一个静态方法")MyClass.class_method() # 输出: 这是一个类方法
MyClass.static_method() # 输出: 这是一个静态方法
动态添加属性和方法
类和实例在运行时可以动态添加属性和方法,增强灵活性。
示例:
class Dynamic:passobj = Dynamic()
obj.new_attr = "新属性"
print(obj.new_attr) # 输出: 新属性def new_method(self):print("这是动态添加的方法")import types
obj.new_method = types.MethodType(new_method, obj)
obj.new_method() # 输出: 这是动态添加的方法
迭代器
类可以实现迭代器协议,使其实例能够在 for
循环中使用。迭代器需要实现 __iter__
和 __next__
方法。
示例:
class MyIterator:def __init__(self, limit):self.limit = limitself.current = 0def __iter__(self):return selfdef __next__(self):if self.current < self.limit:num = self.currentself.current += 1return numelse:raise StopIterationiterator = MyIterator(3)
for num in iterator:print(num)
# 输出:
# 0
# 1
# 2
生成器
生成器是一种简化迭代器创建的方法,通过 yield
关键字生成值。生成器使代码更简洁,节省内存。
示例:
def my_generator(limit):current = 0while current < limit:yield currentcurrent += 1for num in my_generator(3):print(num)
# 输出:
# 0
# 1
# 2
生成器表达式
生成器表达式是一种简洁的生成器的语法,类似于列表推导式,但使用圆括号 ()
。
示例:
gen = (x**2 for x in range(5))
for num in gen:print(num)
# 输出:
# 0
# 1
# 4
# 9
# 16
总结
Python 的类机制提供了强大的面向对象编程支持,使代码组织、复用和扩展变得更加容易。通过理解和掌握以下关键点,可以高效地使用类来构建复杂的应用程序:
- 名称和对象:理解名称与对象的关系,掌握作用域和命名空间的概念。
- 类的定义与实例化:使用
class
关键字定义类,通过构造方法__init__
初始化实例属性。 - 类和实例变量:区分类变量与实例变量,理解它们的共享和独立性。
- 方法对象:掌握实例方法、类方法和静态方法的定义与使用。
- 继承与多重继承:通过继承实现代码复用,理解方法解析顺序(MRO)。
- 私有变量:通过命名约定和
property
控制属性的访问权限,增强封装性。 - 迭代器与生成器:实现迭代器协议,使用生成器简化迭代器创建。
- 高级特性:如描述符、属性、动态添加属性和方法等,提升类的灵活性和功能性。
理解并灵活运用这些类的特性和方法,能够显著提升 Python 程序的组织性、可维护性和功能性。