Python学习笔记之类
1 类练习一
你有一个形如 $ax^2+bx+c$ 的多项式,你要支持如下的操作:
1 A B C
将当前多项式加上 $Ax^2+Bx+C$。2 A
将当前多项式加上 $Ax^2+Ax+A$。3
询问 $ax^2+bx+c=0$ 解的个数。4
输出当前多项式。
1.1 示例程序:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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_str
1.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 导入模块
1
import math
import math
:导入 Python 的数学模块。
1.3.2 初始化函数 __init__
1
2
3
4
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__
1
2
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
1
2
3
4
def add(self, A):
self.a += A
self.b += A
self.c += A
- 功能: 将指定值
A
加到多项式的所有系数上。 - 参数:
A
:要加到每个系数的值。
- 作用: 修改当前实例的系数
a
、b
和c
,使它们都增加A
。
1.3.5 静态方法 que
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@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
- 功能: 求解二次方程
ax^2 + bx + c = 0
的根的个数。 - 参数:
poly
:MyClass
的实例,表示一个二次多项式。
- 返回:
0
:无实根。1
:有一个实根(重根)。2
:有两个不同的实根。float('inf')
:当a
和b
都为0
且c
不为0
时,返回无解。
1.3.6 字符串表示 __str__
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
参数。 - 调用: 可以通过类或实例调用,且不依赖于类的实例。调用时不传递实例或类作为参数。
- 示例:
1 2 3 4 5 6
class MyClass: @staticmethod def my_static_method(): print("This is a static method") MyClass.my_static_method() # 通过类调用
- 定义: 使用
- 普通方法(实例方法):
- 定义: 普通方法定义时需要
self
参数,用于访问实例的属性和其他方法。 - 调用: 必须通过类的实例来调用,调用时自动传递实例作为第一个参数。
- 示例:
1 2 3 4 5 6
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
,表示类本身,而不是实例。 - 调用: 可以通过类或实例调用。调用时自动传递类作为第一个参数。
- 用途: 适合访问或修改类的状态(而非实例状态),例如工厂方法或替代构造函数。
- 示例:
1 2 3 4 5 6 7 8 9 10 11 12 13
class MyClass: class_var = 0 @classmethod def increment_class_var(cls): cls.class_var += 1 @classmethod def create_instance(cls): return cls() MyClass.increment_class_var() # 通过类调用 instance = MyClass.create_instance() # 通过类调用
2.2 属性方法(@property
)
- 定义: 使用
@property
装饰器定义的方法,使其表现得像一个属性,而不是方法。 - 调用: 通过访问属性的方式调用,而不是通过方法调用。
- 用途: 适合将计算结果或只读值暴露为属性而不是方法。
- 示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
class MyClass: def __init__(self, value): self._value = value @property def value(self): return self._value @value.setter def value(self, new_value): self._value = new_value obj = MyClass(10) print(obj.value) # 通过属性访问 obj.value = 20 # 通过属性设置
2.3 只读属性方法(@property
的只读部分)
- 定义:
@property
使方法表现为只读属性,不提供 setter 方法。 - 用途: 适合提供只读的属性访问,而不允许修改。
- 示例:
1 2 3 4 5 6 7 8 9 10 11
class MyClass: def __init__(self, value): self._value = value @property def value(self): return self._value obj = MyClass(10) print(obj.value) # 通过属性访问 # obj.value = 20 # AttributeError: can't set attribute
2.4 @staticmethod
和 @classmethod
的组合
- 定义: 可以在一个类中同时使用静态方法和类方法,以实现不同的功能需求。
- 示例:
1 2 3 4 5 6 7 8 9 10 11
class MyClass: @staticmethod def static_method(): print("This is a static method") @classmethod def class_method(cls): print("This is a class method") MyClass.static_method() MyClass.class_method()
本文由作者按照
CC BY 4.0
进行授权