重构代码

本教程是关于什么的

本教程展示了 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' ) 如果 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' ) 如果 denom < 0: num, denom = -num, -denom x = abs(num) y = abs(denom) 而 x: x, y = y % x, x factor = y return super().__new__(cls , num // 因子, denom // 因子) def __str__(self): return '{}/{}'.format(self.num, self.denom)

提取方法

现在,让我们将最大公约数的搜索提取到一个单独的方法中。为此,请选择语句

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

并按Ctrl+Alt+M。在打开的对话框中键入方法名称gcd,然后单击OK

@staticmethod def gcd(denom, num): x = abs(num) y = abs(denom) 而 x: x, y = y % x, x factor = y 返回因子

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

factor让我们通过使用内联变量重构来摆脱变量。为此,请将插入符号放在变量上并按Ctrl+Alt+N。所有检测到的factor变量都是内联的。

接下来,使用Change signature更改参数名称。为此,请将插入符号放在方法声明行并按Ctrl+F6。在打开的对话框中,将参数denom和分别重命名numxy,然后单击图标节点上一级以更改参数的顺序。

您最终得到以下代码:

@staticmethod def gcd(x, y): x = abs(x) y = abs(y) 而 x: x, y = y % x, x 返回 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 // 因子, denom // 因子) def __str__(self): return ' {}/{}'.format(self.num, self.denom) def gcd(x, y): x = abs(x) y = abs(y) 而 x: x, y = y % x, x 返回是的

将函数移动到另一个文件

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

def gcd(x, y): x = abs(x) y = abs(y) 而 x: x, y = y % x, x 返回 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不能为空') 如果 denom < 0: num, denom = -num, -denom factor = gcd(num, denom) return super().__new__(cls, num // 因子, denom // 因子) 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不能为空') factor = gcd(num, denom) if denom < 0: num, denom = -num, -denom return super().__new__(cls, num // 因子, denom // 因子) def __str__(self ): return '{}/{}'.format(self.num, self.denom) def __add__(self, other): if isinstance(other, int): other = Rational(other, 1) if isinstance(other,有理数):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,从建议列表中选择Make method static,然后按Enter

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

最后,让我们将参数的名称更改othernumber. 为此,请将插入符号放在参数上并按Shift+F6

提取超类

接下来,我们将方法的实现移动__radd____sub____rsub__类中。此外,我们将制作方法__neg____add__抽象。

这就是它的完成方式......将插入符号放在类Rational声明处,在上下文菜单指向Refactor | 提取并选择超类...... 接下来,在打开的对话框中,指定超类的名称(此处为AdditiveMixin)并选择要添加到超类的方法。对于方法__neg__和,选择Make abstract__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 // 因子, denom // 因子) 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)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 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.面额)
最后修改时间:2021 年 3 月 8 日