社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

8个重构技巧使得Python代码更Pythonic

数据STUDIO • 1 年前 • 252 次点击  

1.合并嵌套的if语句

我们从简单的开始。不要像这样嵌套 if 语句,只需将它们合并为一个即可。

if a:
    if b:
        pass

# -> refactor
if a and b:
    pass

2.使用 any 而不是循环

这里我们要检查列表中是否至少有一个正元素。更长的解决方案是遍历所有数字,检查当前数字,然后在条件为真时中断。但是对于这个任务,在 Python 中有一个专门的方法,即 any 函数。如果可迭代对象的任何元素为真,则 any 返回 True。这比手动循环要短得多,也更像 pythonic。

numbers = [-1-2-403-7]
has_positives = False
for n in numbers:
    if n > 0:
        has_positives = True
        break

# -> refactor
has_positives = any(n > 0 for n in numbers)

3.从 for/while 循环中提取语句

很多时候你会看到循环中定义了一个变量,但它永远不会改变。这些都是不必要的操作,所以把它从循环中拉出来,然后你只需要创建一次。

for building in buildings:
    city = 'London'
    addresses.append(building.street_address, city)

# -> refactor
city = 'London'
for building in buildings:
    addresses.append(building.street_address, city)

4.去除只使用一次并立即返回的内联变量

很多时候你会看到代码在最后一个函数中定义了一个变量,一行之后它立即返回。如果清楚函数是干什么的,直接返回结果即可。这样更简洁并且避免了不必要的变量。但是,有时如果不是很清楚函数在做什么,它仍然会有帮助,然后您可以给最后一个变量一个有意义的名称并将其用作自文档代码。

def state_attributes(self):
    """Return the state attributes."""
    state_attr = {
        ATTR_CODE_FORMAT: self.code_format,
        ATTR_CHANGED_BY: self.changed_by,
    }
    return state_attr

# -> refactor
def state_attributes(self):
    """Return the state attributes."""
    return {
        ATTR_CODE_FORMAT: self.code_format,
        ATTR_CHANGED_BY: self.changed_by,
    }

5.用if表达式替换if语句

不用 if else 语句来设置变量的值,你可以像这样用 if 表达式在一行中设置它。不过,这种重构技术有点值得商榷。有些人仍然喜欢第一个选项,这很好。

if condition:
    x = 1
else:
    x = 2

# -> refactor
x = 1 if condition else 2

6.添加保护条款

查看此代码时,很难快速掌握正在发生的事情。有多个 if-else 语句和多个缩进。一旦你仔细观察,你可能会发现第一个 if 语句几乎覆盖了整个函数代码,只是在最后我们有相应的 else 子句,我们只返回 False。

我们可以把这个 else 子句移到最开始。这也称为警卫声明。所以如果条件不成立,我们就不会执行其余的函数代码。这样就去掉了一个 else 子句,现在整个代码中的缩进少了一层。这看起来更清晰,也更容易理解。

def should_i_wear_this_hat(self, hat):
    if isinstance(hat, Hat):
        current_fashion = get_fashion()
        weather_outside = self.look_out_of_window()
        is_stylish = self.evaluate_style(hat, current_fashion)
        if weather_outside.is_raining:
            print("Damn.")
            return True
        else:
            print("Great.")
            return is_stylish
    else:
        return False

# -> refactor
def should_i_wear_this_hat(self, hat):
    if not isinstance(hat, Hat):
        return False

    current_fashion = get_fashion()
    weather_outside = self.look_out_of_window()
    is_stylish = self.evaluate_style(hat, current_fashion)
    if weather_outside.is_raining:
        print("Damn.")
        return True
    else:
        print("Great.")
        return is_stylish

7.将分配移近它们的用途

这是上一个示例的改进代码,但仍然需要一些时间才能理解这里发生的事情。所以我们想检查我们是否应该戴帽子。逻辑是这样的:如果正在下雨,我们总是说 True,如果没有下雨,如果帽子很时尚,我们就说 True。我们可以大大提高此逻辑的可读性的一种简单方法是将分配移至更接近其用法的位置。在使用 if 语句之前让我们先了解天气情况。现在 fashionstyle 变量只在 else 子句中需要,所以将它们向下移动。现在应该更清楚发生了什么。

还记得我的第 4 条提示吗?我们可以进一步缩短代码并立即返回评估样式结果。然而,在这个例子中,我也喜欢 is_stylish 这个名字,因为它让你知道如果帽子很时尚,你就说 True,否则就说 False。所以这里把多余的变量留着就好了。

def should_i_wear_this_hat(self, hat):
    if not isinstance(hat, Hat):
        return False

    current_fashion = get_fashion()
    weather_outside = self.look_out_of_window()
    is_stylish = self.evaluate_style(hat, current_fashion)
    if weather_outside.is_raining:
        print("Damn.")
        return True
    else:
        print("Great.")
        return is_stylish

# -> refactor
def should_i_wear_this_hat(self, hat):
    if not isinstance(hat, Hat):
        return False

    weather_outside = self.look_out_of_window()
    if weather_outside.is_raining:
        print("Damn.")
        return True
    else:
        print("Great.")
        current_fashion = get_fashion()
        return self.evaluate_style(hat, current_fashion)
        # is_stylish = self.evaluate_style(hat, current_fashion)
         # return is_stylish

8.简化序列检查

这是我经常看到的另一件事。当你需要检查集合中是否有元素时,例如在列表中,你不需要写if len(your_list) > 0. 你可以简单地说if your_list。这是 pep 8 推荐的方法,也称为真值测试。这是可能的,因为在 Python 中,空序列和集合的计算结果为 False。所以这可以应用于字符串、元组、列表、字典和集合。

if len(list_of_hats) > 0:
    hat_to_wear = choose_hat(list_of_hats)

# -> refactor
if list_of_hats:
    hat_to_wear = choose_hat(list_of_hats)

🏴‍☠️宝藏级🏴‍☠️ 原创公众号『数据STUDIO』内容超级硬核。公众号以Python为核心语言,垂直于数据科学领域,包括可戳👉 PythonMySQL数据分析数据可视化机器学习与数据挖掘爬虫 等,从入门到进阶!

长按👇关注- 数据STUDIO -设为星标,干货速递

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/162155
 
252 次点击