PyCharm 重构教程
最后修改时间:2023 年 9 月 5 日本教程的内容
本教程通过使用有理数的简单类示例展示了 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
并按。在打开的对话框中输入方法名称,然后单击“确定”:CtrlAlt0Mgcd
@staticmethod
def gcd(denom, num):
x = abs(num)
y = abs(denom)
while x:
x, y = y % x, x
factor = y
return factor
内联局部变量并更改方法签名
factor
让我们通过使用内联变量重构来摆脱变量。为此,请将脱字符号放在变量处,然后按。所有检测到的变量都是内联的。CtrlAlt0Nfactor
接下来,使用更改签名更改参数名称。为此,请将插入符号放在方法声明行并按。在打开的对话框中,将参数和分别重命名为和,然后单击更改参数的顺序。CtrlF6denom
num
x
y
您最终得到以下代码:
@staticmethod
def gcd(x, y):
x = abs(x)
y = abs(y)
while x:
x, y = y % x, x
return y
使用快速修复
现在,让我们将现有的静态方法转换为函数。为此,请按,从建议列表中选择将静态方法转换为函数,然后按:AltEnterEnter
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
声明处,然后按。在打开的对话框中指定目标文件util.py的完全限定路径。该文件不存在,但会自动创建:F6
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)
到一个单独的方法中。为此,请将插入符号放在上述表达式处,然后按并在打开的对话框中键入新方法名称。CtrlAlt0Mfrom_int
最后,将插入符号放在方法from_int
声明处,按,从建议列表中选择“使方法静态”,然后按:AltEnterEnter
@staticmethod
def from_int(other):
return Rational(other, 1)
最后,我们将参数名称更改other
为number
。为此,请将插入符号放在参数处,然后按。ShiftF6
提取超类
接下来,我们将把方法__radd__
,的实现__sub__
移至__rsub__
超类中。此外,我们还将创建方法__neg__
和__add__
抽象。
这就是它的完成方式...将脱字符号放在类Rational
声明处,在上下文菜单上指向Refactor | 提取并选择超类...。接下来,在打开的对话框中,指定超类的名称(此处为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)
感谢您的反馈意见!