Python学习笔记之类

2225 字
11 分钟
Python学习笔记之类

1 类练习一#

你有一个形如 ax2+bx+cax^2+bx+c 的多项式,你要支持如下的操作:

  • 1 A B C 将当前多项式加上 Ax2+Bx+CAx^2+Bx+C
  • 2 A 将当前多项式加上 Ax2+Ax+AAx^2+Ax+A
  • 3 询问 ax2+bx+c=0ax^2+bx+c=0 解的个数。
  • 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_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 导入模块#

import math
  • import 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 的实例时,abc 将被赋值给实例的属性 self.aself.bself.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:要加到每个系数的值。
  • 作用: 修改当前实例的系数 abc,使它们都增加 A

1.3.5 静态方法 que#

@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 的根的个数。
  • 参数:
    • polyMyClass 的实例,表示一个二次多项式。
  • 返回:
    • 0:无实根。
    • 1:有一个实根(重根)。
    • 2:有两个不同的实根。
    • float('inf'):当 ab 都为 0c 不为 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_strb_strc_str:分别表示 abc 的字符串形式。
    • 根据 bc 的符号,格式化字符串,确保 +- 正确显示。
  • 返回: 多项式的标准字符串格式,如 2*x^2 - 3*x + 4

1.4 静态方法修饰器#

在 Python 中,静态方法(@staticmethod)和普通方法(实例方法)有以下主要区别:

1.4.1 定义和调用方式#

  • 静态方法(@staticmethod:
    • 定义: 使用 @staticmethod 装饰器定义的方法,不需要 self 参数。
    • 调用: 可以通过类或实例调用,且不依赖于类的实例。调用时不传递实例或类作为参数。
    • 示例:
      class MyClass:
      @staticmethod
      def 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
    @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 装饰器定义的方法,使其表现得像一个属性,而不是方法。
  • 调用: 通过访问属性的方式调用,而不是通过方法调用。
  • 用途: 适合将计算结果或只读值暴露为属性而不是方法。
  • 示例:
    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 方法。
  • 用途: 适合提供只读的属性访问,而不允许修改。
  • 示例:
    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 的组合#

  • 定义: 可以在一个类中同时使用静态方法和类方法,以实现不同的功能需求。
  • 示例:
    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()

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!

赞助
Python学习笔记之类
https://www.0x3f.foo/posts/pythonclasslearning/
作者
Dignite
发布于
2024-08-28
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
Dignite
When nothing goes right, go left.
公告
欢迎来到我的博客!这是一则示例公告。
分类
标签
站点统计
文章
146
分类
5
标签
271
总字数
314,753
运行时长
0
最后活动
0 天前

目录