Python面向对象编程:深入理解属性和方法

面向对象编程(OOP)是Python编程的核心范式,而属性和方法是构建类的两大基石。本文将全面讲解Python中属性和方法的各类特性和使用技巧,帮助你掌握面向对象编程的精髓。

一、类属性与实例属性

1. 类属性

类属性属于类本身,被所有实例共享

class Dog:
    # 类属性
    species = "Canis familiaris"
    count = 0  # 用于统计实例数量
    
    def __init__(self, name):
        self.name = name  # 实例属性
        Dog.count += 1

2. 实例属性

每个实例独有的属性,通常在__init__中初始化

class Student:
    def __init__(self, name, score):
        self.name = name
        self.score = score
        self.grade = self.calculate_grade()
        
    def calculate_grade(self):
        return 'A' if self.score >= 90 else 'B'

 3. 属性访问规则

print(Dog.species)  # 通过类访问类属性
buddy = Dog("Buddy")
print(buddy.name)   # 通过实例访问实例属性
print(buddy.species) # 通过实例访问类属性(会向上查找)

二、实例方法、类方法与静态方法

1. 实例方法

  • 实例方法就是函数,至少有一个指向实例对象的形参self  

最常用的方法类型,第一个参数为self

class Circle:
    def __init__(self, radius):
        self.radius = radius
    
    # 实例方法
    def area(self):
        return 3.14 * self.radius ** 2

2. 类方法

使用@classmethod装饰器,第一个参数为cls
(

  • 说明

    • 类方法需要使用@classmethod装饰器定义

    • 类方法至少有一个形参用于绑定类,约定为 cls

    • 类和该类的实例都可以调用类方法

    • 类方法不能访问此类创建的对象的实例属性

)

class Pizza:
    def __init__(self, ingredients):
        self.ingredients = ingredients
    
    @classmethod
    def margherita(cls):
        return cls(["mozzarella", "tomatoes"])
    
    @classmethod
    def prosciutto(cls):
        return cls(["mozzarella", "tomatoes", "ham"])

3. 静态方法

使用@staticmethod装饰器,没有默认参数

(

  • 静态方法定义在类的内部,作用域是类内部

  • 说明

    • 使用@staticmethod装饰器定义

    • 不需要self和cls参数

    • 通过类或类实例调用

    • 可以访问类属性,不能访问实例属性

)

class MathUtils:
    @staticmethod
    def add(a, b):
        return a + b
    
    @staticmethod
    def multiply(a, b):
        return a * b

三、属性访问控制

1. 私有属性(约定)

以单下划线开头,提示"不要直接访问"

class BankAccount:
    def __init__(self, balance):
        self._balance = balance  # 提示这是受保护的

2. 真正私有属性

以双下划线开头,Python会进行名称改写(Name Mangling)

 作用:通过改变属性名称来实现一定程度的"私有化"。

 改写后的名称格式为:

 _类名__原属性名

class Secret:
    def __init__(self):
        self.__secret_code = "12345"  # 实际变为_Secret__secret_code

3. 属性装饰器

属性装饰器(@property)是Python中一种强大的特性,它允许你将方法"伪装"成属性来访问,从而实现对属性的更精细控制。 

使用@property控制属性访问

class Temperature:
    def __init__(self, celsius):
        self._celsius = celsius
    
    @property
    def celsius(self):
        return self._celsius
    
    @celsius.setter
    def celsius(self, value):
        if value < -273.15:
            raise ValueError("温度不能低于绝对零度")
        self._celsius = value
    
    @property
    def fahrenheit(self):
        return self._celsius * 9/5 + 32

四、特殊方法(魔术方法)

魔术方法是一种特殊的方法,用双下划线包裹,例如__init____str____add__等。这些方法允许您自定义类的行为,以便与内置Python功能(如+运算符、迭代、字符串表示等)交互。  

常用方法
  1. __init__(self, ...): 初始化对象,通常用于设置对象的属性。

  2. __str__(self): 定义对象的字符串表示形式,可通过str(object)print(object)调用。例如,您可以返回一个字符串,描述对象的属性。

  3. __repr__(self): 定义对象的“官方”字符串表示形式,通常用于调试。可通过repr(object)调用。

  4. __len__(self): 定义对象的长度,可通过len(object)调用。通常在自定义容器类中使用。

  5. __getitem__(self, key): 定义对象的索引操作,使对象可被像列表或字典一样索引。例如,object[key]

  6. __setitem__(self, key, value): 定义对象的赋值操作,使对象可像列表或字典一样赋值。例如,object[key] = value

  7. __delitem__(self, key): 定义对象的删除操作,使对象可像列表或字典一样删除元素。例如,del object[key]

  8. __iter__(self): 定义迭代器,使对象可迭代,可用于for循环。

  9. __next__(self): 定义迭代器的下一个元素,通常与__iter__一起使用。

  10. __add__(self, other): 定义对象相加的行为,使对象可以使用+运算符相加。例如,object1 + object2

  11. __sub__(self, other): 定义对象相减的行为,使对象可以使用-运算符相减。

  12. __eq__(self, other): 定义对象相等性的行为,使对象可以使用==运算符比较。

  13. __lt__(self, other): 定义对象小于其他对象的行为,使对象可以使用<运算符比较。

  14. __gt__(self, other): 定义对象大于其他对象的行为,使对象可以使用>运算符比较。

  15. __call__(self, other) 是一个特殊的方法(也称为“魔法方法”),它允许一个对象像函数一样被调用。

 

1. 对象表示

__str__  和 __repr__  方法用于定义对象的字符串表示形式。 __str__  方法的作用是返回对象的可读性良好的字符串表示,通常用于用户友好的输出,比如当使用 print()  函数打印对象时会调用 __str__  方法。而 __repr__  方法的作用是返回对象的“官方”字符串表示,理想情况下,该字符串可以用来重新创建对象,方便调试和记录日志等场景。例如在交互式环境中直接输入对象时会调用 __repr__  方法。 

class Book:
    def __init__(self, title, author):
        self.title = title
        self.author = author
    
    def __str__(self):
        return f"《{self.title}》 - {self.author}"
    
    def __repr__(self):
        return f"Book('{self.title}', '{self.author}')"

 2. 运算符重载

 运算符重载允许我们定义自定义类的实例在使用运算符(如 + 、 *  等)时的行为。比如在下述 Vector  类中, __add__  方法定义了向量相加的操作,当使用 +  运算符对两个 Vector  实例进行操作时,会调用 __add__  方法; __mul__  方法定义了向量与标量相乘的操作,使用 *  运算符时会调用 __mul__  方法。这样就可以让自定义的 Vector  类像内置的数值类型一样进行运算。

class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def __add__(self, other):
        return Vector(self.x + other.x, self.y + other.y)
    
    def __mul__(self, scalar):
        return Vector(self.x * scalar, self.y * scalar)

 3. 容器类型方法

__len__  方法返回容器中元素的数量,当使用 len()  函数获取容器对象的长度时会调用该方法。 __getitem__  方法允许通过索引(如 [index] )来访问容器中的元素,当使用类似 inventory[i]  的方式访问 Inventory  类的实例时会调用该方法。 __contains__  方法用于判断容器中是否包含某个元素,当使用 in  关键字检查元素是否在容器中时会调用该方法。通过这些方法,自定义的 Inventory  类就可以像内置的容器类型(如列表、元组等)一样使用。 

class Inventory:
    def __init__(self):
        self.items = []
    
    def __len__(self):
        return len(self.items)
    
    def __getitem__(self, index):
        return self.items[index]
    
    def __contains__(self, item):
        return item in self.items

五、动态属性管理

1. __dict__属性

查看对象的所有属性

class Person:
    def __init__(self, name):
        self.name = name

p = Person("Alice")
print(p.__dict__)  # {'name': 'Alice'}

 2. 动态添加属性

class Dynamic:
    pass

obj = Dynamic()
obj.new_attr = "动态添加的属性"

3. __slots__优化

限制实例能拥有的属性,节省内存

class Point:
    __slots__ = ['x', 'y']
    
    def __init__(self, x, y):
        self.x = x
        self.y = y

 

六、最佳实践

  1. 遵循命名约定

    • 公共属性:normal

    • 保护属性:_protected

    • 私有属性:__private

  2. 合理使用属性装饰器

    • 需要计算或验证时使用@property

    • 保持简单属性直接访问

  3. 方法选择原则

    • 需要访问实例:实例方法

    • 需要访问类但不依赖实例:类方法

    • 既不访问类也不访问实例:静态方法

  4. 文档字符串
    为所有公共方法和属性添加docstring

class Calculator:
    """一个简单的计算器类"""
    
    def add(self, a, b):
        """返回两个数字的和
        
        Args:
            a: 第一个数字
            b: 第二个数字
            
        Returns:
            两数之和
        """
        return a + b

 

七、总结

Python中的属性和方法构成了面向对象编程的基础:

  1. 属性

    • 类属性 vs 实例属性

    • 属性访问控制

    • 动态属性管理

  2. 方法

    • 实例方法、类方法、静态方法

    • 特殊方法(魔术方法)实现运算符重载

    • 方法装饰器的使用

掌握这些概念后,你将能够:

  • 设计更合理的类结构

  • 实现更优雅的对象接口

  • 编写更易维护的面向对象代码

  • 充分利用Python的动态特性

面向对象编程是一个需要不断实践的领域,建议从简单的类开始,逐步尝试更复杂的设计模式,最终你将能够构建出强大而灵活的Python应用程序。

 

 

 

你可能感兴趣的:(python基础知识点,python,开发语言,属性和方法)