赞
踩
在 Python 的对象导向编程中,
self
是一个至关重要的概念,它代表了类的实例本身。通过使用self
,可以访问类中定义的属性和方法。
self
的基本概念self
是类的一个实例,它指向内存中的当前对象。当创建类的实例时,Python 会自动将这个实例作为第一个参数传递给类的方法。
定义类和实例
定义一个简单的类 Car
,它有两个属性:make
和 year
,以及一个方法 display_info
用来显示这些信息。
class Car:
def __init__(self, make, year):
self.make = make
self.year = year
def display_info(self):
print(f"This car is a {self.year} {self.make}.")
# 创建一个 Car 类的实例
my_car = Car("Toyota", 2022)
my_car.display_info()
# This car is a 2022 Toyota.
在上面的代码中:
__init__
方法是一个特殊的方法,被称为构造器,用于初始化新创建的对象。self.make
和 self.year
表示将传入的参数值赋值给实例的属性。display_info
方法使用 self
来访问这些属性。self
在方法调用中的角色self
不仅用于访问属性,还可以调用同一类中的其他方法。
调用其他方法
在 Car
类中添加了新方法,用于检查车辆是否属于老爷车。
class Car:
def __init__(self, make, year):
self.make = make
self.year = year
def display_info(self):
print(f"This car is a {self.year} {self.make}.")
def calculate_age(self, current_year):
return current_year - self.year
def is_vintage(self, current_year=2024):
# 调用 calculate_age 方法来获取车辆年龄
age = self.calculate_age(current_year)
return age > 25
# 检查车辆是否为老爷车
my_car = Car("Ford", 1968)
print("Is this car vintage?", my_car.is_vintage()) # 输出: Is this car vintage? True
calculate_age
方法:这个新方法接收一个年份作为参数,用来计算车辆的年龄。is_vintage
方法中的调用:在 is_vintage
方法中,使用 self.calculate_age(current_year)
来调用 calculate_age
方法。这展示了如何使用 self
调用同一类中的其他方法。is_vintage
方法返回一个布尔值,根据 calculate_age
方法返回的车龄来判断是否超过25年。self
在面向对象的编程中,继承是一个核心概念。self
在子类中同样有效,它能访问父类中定义的属性和方法。
创建基类和子类
假设有一个基类 Vehicle
,和一个从 Vehicle
继承的子类 Truck
。
class Vehicle:
def __init__(self, make, year):
self.make = make
self.year = year
def display_info(self):
print(f"This car is a {self.year} {self.make}.")
class Truck(Vehicle):
def __init__(self, make, year, payload):
super().__init__(make, year)
self.payload = payload
def display_info(self):
super().display_info()
print(f"It can carry up to {self.payload} tons.")
# 创建一个 Truck 实例
my_truck = Truck("Ford", 2019, 5)
my_truck.display_info()
# This car is a 2019 Ford.
# It can carry up to 5 tons.
在这个例子中:
Truck
类通过 super()
调用了 Vehicle
类的 __init__
方法。display_info
方法同样展示了如何使用 super()
调用父类的方法,并扩展了额外的功能。小拓展:方法重写
Truck
类确实对父类 Vehicle
的 display_info
方法进行了重写(这个过程通常称为方法的重写或覆盖)。这里是如何操作的:
Vehicle
类有一个 display_info
方法,它打印出车辆的年份和制造商。Truck
类继承自 Vehicle
,并重写了 display_info
方法。在 Truck
类的 display_info
方法中,首先通过 super().display_info()
调用了父类 Vehicle
的 display_info
方法,从而能够先输出基本的车辆信息。Truck
类的 display_info
方法扩展了更多的功能,它还打印出载重量的信息。self
的注意事项和扩展虽然 self
在使用上看似直观,但在实际开发中可能会遇到一些需要特别注意的情况。
self
的命名不是强制的在 Python 中,self
只是一个习惯用法。可以使用任何其他名称作为实例引用的第一个参数,但强烈建议遵循这个约定以保持代码的清晰性和一致性。
self
与类属性混淆类属性属于类本身,与任何实例无关。如果使用 self
访问类属性,可能会引起不必要的混淆。正确的做法是通过类名来访问类属性。
类属性与实例属性是两种不同的属性,它们的用途和行为也有所区别:
self
关键字定义的,通常在 __init__
方法中初始化。每个类的实例都会拥有自己的实例属性副本,实例间的属性互不影响。示例说明
考虑下面的类定义,其中包含类属性和实例属性:
class Sample:
class_attr = 10 # 类属性,所有实例共享
def __init__(self, value):
self.instance_attr = value # 实例属性,每个实例独有
访问类属性的正确方式
虽然可以通过实例使用 self
来访问类属性,这在技术上是可行的,但这样做可能会导致代码理解上的困难。特别是在存在同名实例属性的情况下,这样会使得代码更加难以追踪和维护。
正确的做法是通过类名来访问类属性,如 Sample.class_attr
,这样可以明确地表明该属性是属于类的,而不是某个实例的。
为什么通过类名访问类属性更好?
self
可能导致访问的是实例属性而非类属性。通过类名访问可以避免这种混淆。推荐我的相关专栏: python 错误记录
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。