PyCharm 2025.3 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 ,在建议列表中选择 将静态方法转换为函数 ,然后按下 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

将函数移动到另一个文件

现在,我们将把该函数移动到单独的文件,并添加一条 import 语句。 为此,将插入符号置于函数 gcd 的声明处,然后按下 F6。 在打开的 对话框 中,指定目标文件 util.py 的完全限定路径。 该文件尚不存在,但会自动创建:

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

还会自动添加 import 语句。 因此,文件 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年 12月 2日