Python学习笔记之类
1 类练习一
你有一个形如 的多项式,你要支持如下的操作:
1 A B C将当前多项式加上 。2 A将当前多项式加上 。3询问 解的个数。4输出当前多项式。
1.1 示例程序:
class MyClass: import math def __init__(self, a, b, c): self.a = a self.b = b self.c = c
def __add__(self, other): return MyClass(self.a + other.a, self.b + other.b, self.c + other.c)
def add(self, A): self.a += A self.b += A self.c += A
@staticmethod def que(poly): a, b, c = poly.a, poly.b, poly.c if a == 0: if b == 0: return 0 if c != 0 else float('inf') return 1 discriminant = b * b - 4 * a * c if discriminant > 0: return 2 elif discriminant == 0: return 1 else: return 0
def __str__(self): a_str = str(self.a) if self.b >= 0: b_str = "+" + str(self.b) else: b_str = "-" + str(-self.b) if self.c >= 0: c_str = "+" + str(self.c) else: c_str = "-" + str(-self.c)
if self.b == 0 and self.c == 0: return a_str + "*x^2" elif self.b == 0: return a_str + "*x^2" + c_str elif self.c == 0: return a_str + "*x^2" + b_str + "*x" else: return a_str + "*x^2" + b_str + "*x" + c_str1.2 特殊方法与普通方法
首先我们注意到,有些函数是由带着前后的 __ ,而有些函数是直接的名称。在 Python 中,带有双下划线 __ 的函数(称为“特殊方法”或“魔法方法”)与普通方法有几个显著的区别:
1.2.1 特殊方法(魔法方法)
-
定义: 特殊方法是以双下划线开始和结束的方法,例如
__init__,__add__,__str__,__eq__等。 -
目的: 这些方法是 Python 的内置机制的一部分,提供了对 Python 内建操作的自定义。它们允许用户定义对象的行为,使其能够响应特定的操作或行为。
-
用法:
__init__: 构造函数,用于初始化对象。__add__: 实现加法操作 (+) 的行为。__str__: 定义对象的字符串表示。__eq__: 定义对象的相等性比较(==)。__call__: 使对象能够像函数一样被调用。
这些方法通常不直接调用,而是通过运算符或内置函数间接调用。例如,
obj + other会调用obj.__add__(other)。 -
特殊性: 特殊方法在 Python 内部有特殊的作用,它们定义了对象在特定操作中的行为。它们是 Python 数据模型的一部分,并且可以被 Python 的内置函数和操作所自动调用。
1.2.2 普通方法
-
定义: 普通方法是类中定义的以单个下划线或没有下划线的函数,例如
add,subtract,display等。 -
目的: 这些方法用于定义类的实例可以执行的行为或操作。它们通常用于实现类的业务逻辑。
-
用法:
add: 例如,用于执行类实例的某个具体操作,可能改变实例的状态或执行计算。display: 显示对象的状态或信息。
普通方法可以被实例通过点运算符调用,例如
obj.add(value)。 -
特殊性: 普通方法不具备特殊的内置功能或自动触发机制,它们是用户定义的用于实现类功能的普通函数。
1.2.3总结
-
特殊方法:
- 由双下划线包围(如
__init__,__add__)。 - 与 Python 内部机制和运算符操作相关。
- 通常不直接调用,而是通过 Python 内置操作间接调用。
- 用于自定义对象在内建操作中的行为。
- 由双下划线包围(如
-
普通方法:
- 没有双下划线。
- 用于实现类的具体业务逻辑。
- 通过对象实例直接调用。
1.3代码详解
1.3.1 导入模块
import mathimport math:导入 Python 的数学模块。
1.3.2 初始化函数 __init__
def __init__(self, a, b, c): self.a = a self.b = b self.c = c-
功能: 构造函数,用于初始化
MyClass的实例。 -
参数:
a:二次项的系数。b:一次项的系数。c:常数项的系数。
-
作用: 当创建
MyClass的实例时,a、b和c将被赋值给实例的属性self.a、self.b和self.c。
1.3.3 加法运算符重载 __add__
def __add__(self, other): return MyClass(self.a + other.a, self.b + other.b, self.c + other.c)- 功能: 实现加法运算符
+的重载,使得两个MyClass实例可以通过+操作符相加。 - 参数:
other:另一个MyClass实例。
- 返回: 返回一个新的
MyClass实例,其系数是两个实例对应系数的和。
1.3.4 修改系数 add
def add(self, A): self.a += A self.b += A self.c += A- 功能: 将指定值
A加到多项式的所有系数上。 - 参数:
A:要加到每个系数的值。
- 作用: 修改当前实例的系数
a、b和c,使它们都增加A。
1.3.5 静态方法 que
@staticmethoddef que(poly): a, b, c = poly.a, poly.b, poly.c if a == 0: if b == 0: return 0 if c != 0 else float('inf') return 1 discriminant = b * b - 4 * a * c if discriminant > 0: return 2 elif discriminant == 0: return 1 else: return 0- 功能: 求解二次方程
ax^2 + bx + c = 0的根的个数。 - 参数:
poly:MyClass的实例,表示一个二次多项式。
- 返回:
0:无实根。1:有一个实根(重根)。2:有两个不同的实根。float('inf'):当a和b都为0且c不为0时,返回无解。
1.3.6 字符串表示 __str__
def __str__(self): a_str = str(self.a) if self.b >= 0: b_str = "+" + str(self.b) else: b_str = "-" + str(-self.b) if self.c >= 0: c_str = "+" + str(self.c) else: c_str = "-" + str(-self.c)
if self.b == 0 and self.c == 0: return a_str + "*x^2" elif self.b == 0: return a_str + "*x^2" + c_str elif self.c == 0: return a_str + "*x^2" + b_str + "*x" else: return a_str + "*x^2" + b_str + "*x" + c_str- 功能: 返回多项式的字符串表示形式。
- 构造:
a_str、b_str、c_str:分别表示a、b和c的字符串形式。- 根据
b和c的符号,格式化字符串,确保+和-正确显示。
- 返回: 多项式的标准字符串格式,如
2*x^2 - 3*x + 4。
1.4 静态方法修饰器
在 Python 中,静态方法(@staticmethod)和普通方法(实例方法)有以下主要区别:
1.4.1 定义和调用方式
- 静态方法(
@staticmethod):- 定义: 使用
@staticmethod装饰器定义的方法,不需要self参数。 - 调用: 可以通过类或实例调用,且不依赖于类的实例。调用时不传递实例或类作为参数。
- 示例:
class MyClass:@staticmethoddef my_static_method():print("This is a static method")MyClass.my_static_method() # 通过类调用
- 定义: 使用
- 普通方法(实例方法):
- 定义: 普通方法定义时需要
self参数,用于访问实例的属性和其他方法。 - 调用: 必须通过类的实例来调用,调用时自动传递实例作为第一个参数。
- 示例:
class MyClass:def my_instance_method(self):print("This is an instance method")obj = MyClass()obj.my_instance_method() # 通过实例调用
- 定义: 普通方法定义时需要
1.4.2 访问权限
- 静态方法:
- 不访问类的属性或实例的属性。
- 适合执行与类的实例无关的任务,如工具函数或辅助函数。
- 普通方法:
- 可以访问和修改实例的属性和方法。
- 适合实现与实例状态相关的操作和行为。
1.4.3. 使用场景
- 静态方法:
- 用于实现功能性代码,与对象的状态无关。
- 适合需要与类相关,但不依赖于类或实例状态的函数。
- 普通方法:
- 用于操作实例的状态或执行依赖于实例的操作。
- 适合需要访问和修改对象的内部数据或状态的函数。
2 拓展:关于类的其他修饰器
除了 @staticmethod 和普通方法,还有其他几种常用的类修饰器(装饰器)和方法修饰器,主要包括:
2.1 类方法(@classmethod)
- 定义: 使用
@classmethod装饰器定义的方法,第一个参数是cls,表示类本身,而不是实例。 - 调用: 可以通过类或实例调用。调用时自动传递类作为第一个参数。
- 用途: 适合访问或修改类的状态(而非实例状态),例如工厂方法或替代构造函数。
- 示例:
class MyClass:class_var = 0@classmethoddef increment_class_var(cls):cls.class_var += 1@classmethoddef create_instance(cls):return cls()MyClass.increment_class_var() # 通过类调用instance = MyClass.create_instance() # 通过类调用
2.2 属性方法(@property)
- 定义: 使用
@property装饰器定义的方法,使其表现得像一个属性,而不是方法。 - 调用: 通过访问属性的方式调用,而不是通过方法调用。
- 用途: 适合将计算结果或只读值暴露为属性而不是方法。
- 示例:
class MyClass:def __init__(self, value):self._value = value@propertydef value(self):return self._value@value.setterdef value(self, new_value):self._value = new_valueobj = MyClass(10)print(obj.value) # 通过属性访问obj.value = 20 # 通过属性设置
2.3 只读属性方法(@property 的只读部分)
- 定义:
@property使方法表现为只读属性,不提供 setter 方法。 - 用途: 适合提供只读的属性访问,而不允许修改。
- 示例:
class MyClass:def __init__(self, value):self._value = value@propertydef value(self):return self._valueobj = MyClass(10)print(obj.value) # 通过属性访问# obj.value = 20 # AttributeError: can't set attribute
2.4 @staticmethod 和 @classmethod 的组合
- 定义: 可以在一个类中同时使用静态方法和类方法,以实现不同的功能需求。
- 示例:
class MyClass:@staticmethoddef static_method():print("This is a static method")@classmethoddef class_method(cls):print("This is a class method")MyClass.static_method()MyClass.class_method()
支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!
无穷大?