PyCharm 2025.2 Help

PyCharm 重构教程

本教程的内容

本教程展示了 PyCharm 中可用的一些重构操作,使用了一个简单类的示例,该类使用了有理数。

先决条件

确保满足以下前提条件:

  • 您使用的是 PyCharm 2016.2 或更高版本。

  • 项目已创建。

准备示例

在您的项目中创建一个 Python 文件 rational.py 并添加以下代码:

from collections import namedtuple class Rational(namedtuple('Rational', ['num', 'denom'])): def __new__(cls, num, denom): if denom == 0: raise ValueError('Denominator cannot be null') if denom < 0: num, denom = -num, -denom return super().__new__(cls, num, denom) def __str__(self): return '{}/{}'.format(self.num, self.denom)

简化有理数

让我们通过将分子和分母除以最大公约数来简化一个有理数:

from collections import namedtuple class Rational(namedtuple('Rational', ['num', 'denom'])): def __new__(cls, num, denom): if denom == 0: raise ValueError('Denominator cannot be null') if denom < 0: num, denom = -num, -denom x = abs(num) y = abs(denom) while x: x, y = y % x, x factor = y return super().__new__(cls, num // factor, denom // factor) def __str__(self): return '{}/{}'.format(self.num, self.denom)

提取方法

现在,让我们将寻找最大公约数的逻辑提取到一个单独的方法中。 为此,选择这些语句

x = abs(num) y = abs(denom) while x: x, y = y % x, x factor = y

然后按 Ctrl+Alt+M。 在打开的 对话框 中,输入方法名称 gcd ,然后点击 确定

@staticmethod def gcd(denom, num): x = abs(num) y = abs(denom) while x: x, y = y % x, x factor = y return factor

内联局部变量并更改方法签名

让我们通过使用 内联变量 重构来移除变量 factor。 为此,将光标放在变量上并按 Ctrl+Alt+N。 所有检测到的 factor 变量都已内联。

接下来,使用 更改签名 更改参数名称。 为此,将光标放在方法声明行上并按 Ctrl+F6。 在打开的 对话框 中,将参数 denomnum 重命名为 xy ,并点击 更改参数顺序。

您将得到以下代码:

@staticmethod def gcd(x, y): x = abs(x) y = abs(y) while x: x, y = y % x, x return y

使用快速修复

现在,让我们将现有的静态方法转换为函数。 为此,按 Alt+Enter ,从建议列表中选择 将 static 方法转换为函数 并按 Enter

from collections import namedtuple class Rational(namedtuple('Rational', ['num', 'denom'])): def __new__(cls, num, denom): if denom == 0: raise ValueError('Denominator cannot be null') if denom < 0: num, denom = -num, -denom factor = gcd(num, denom) return super().__new__(cls, num // factor, denom // factor) def __str__(self): return '{}/{}'.format(self.num, self.denom) def gcd(x, y): x = abs(x) y = abs(y) while x: x, y = y % x, x return y

将函数移动到另一个文件

现在,我们将函数移动到一个单独的文件并添加导入语句。 为此,将光标放在函数 gcd 声明上并按 F6。 在打开的 对话框 中,指定目标文件的完全限定路径 util.py 。 此文件不存在,但会自动创建:

def gcd(x, y): x = abs(x) y = abs(y) while x: x, y = y % x, x return y

导入语句也会自动添加。 因此,文件 rational.py 如下所示:

from collections import namedtuple from util import gcd class Rational(namedtuple('Rational', ['num', 'denom'])): def __new__(cls, num, denom): if denom == 0: raise ValueError('Denominator cannot be null') if denom < 0: num, denom = -num, -denom factor = gcd(num, denom) return super().__new__(cls, num // factor, denom // factor) def __str__(self): return '{}/{}'.format(self.num, self.denom)

进一步修改 Rational 类

添加魔术方法

接下来,让我们为类 Rational 的对象添加加法/减法操作的魔术方法声明:

from collections import namedtuple from util import gcd class Rational(namedtuple('Rational', ['num', 'denom'])): def __new__(cls, num, denom): if denom == 0: raise ValueError('Denominator cannot be null') factor = gcd(num, denom) if denom < 0: num, denom = -num, -denom return super().__new__(cls, num // factor, denom // factor) def __str__(self): return '{}/{}'.format(self.num, self.denom) def __add__(self, other): if isinstance(other, int): other = Rational(other, 1) if isinstance(other, Rational): new_num = self.num * other.denom + other.num * self.denom new_denom = self.denom * other.denom return Rational(new_num, new_denom) return NotImplemented def __neg__(self): return Rational(-self.num, self.denom) def __radd__(self, other): return self + other def __sub__(self, other): return self + (-other) def __rsub__(self, other): return -self + other

提取方法并使用快速修复

接下来,我们将表达式 Rational(other, 1) 提取到一个单独的方法中。 为此,将光标放在上述表达式上,按 Ctrl+Alt+M ,并在打开的 对话框 中输入新方法名称 from_int

最后,将光标放在方法 from_int 声明上,按 Alt+Enter ,从建议列表中选择 将方法设为静态 ,然后按 Enter

@staticmethod def from_int(other): return Rational(other, 1)

最后,让我们将参数 other 的名称更改为 number。 为此,将光标放在参数上并按 Shift+F6

提取超类

接下来,我们将方法 __radd____sub____rsub__ 的实现移动到一个超类中。 此外,我们将方法 __neg____add__ 设为抽象方法。

操作方法如下……将光标放在类 Rational 声明上,在上下文菜单中指向 重构 | 提取 并选择 超类...。 接下来,在打开的对话框中,指定超类的名称(此处为 AdditiveMixin ),并选择要添加到超类的方法。 对于方法 __neg____add__ ,请选中列 设为抽象 中的复选框。 有关更多信息,请参见 提取超类

最终得到以下代码:

from abc import abstractmethod, ABCMeta from collections import namedtuple from util import gcd class AdditiveMixin(metaclass=ABCMeta): @abstractmethod def __add__(self, other): pass @abstractmethod def __neg__(self): pass def __radd__(self, other): return self + other def __sub__(self, other): return self + (-other) def __rsub__(self, other): return -self + other class Rational(namedtuple('Rational', ['num', 'denom']), AdditiveMixin): def __new__(cls, num, denom): if denom == 0: raise ValueError('Denominator cannot be null') factor = gcd(num, denom) if denom < 0: num, denom = -num, -denom return super().__new__(cls, num // factor, denom // factor) def __str__(self): return '{}/{}'.format(self.num, self.denom) def __add__(self, other): if isinstance(other, int): other = self.from_int(other) if isinstance(other, Rational): new_num = self.num * other.denom + other.num * self.denom new_denom = self.denom * other.denom return Rational(new_num, new_denom) return NotImplemented def from_int(self, number): return Rational(number, 1) def __neg__(self): return Rational(-self.num, self.denom)
最后修改日期: 2025年 9月 26日