pythonic code_Pythonic Code (Part I)

前言

本文是 Clean Code in Python 这本书的第二章书的读书笔记。

本书主要讲述怎么写出更具阅读性、以及更好维护的 python 代码。

第二章主要介绍怎么写出更 Pythonic 的代码。

Indexes and Slices

对于列表和元组这类的数据结构,更 Pythonic 的做法是尽量使用 索引 以及 切片 来操作里面的元素,直接上代码。展示怎么使用 索引

>>> my_numbers = (4, 5, 3, 9)

>>> my_numbers[-1]

9

>>> my_numbers[-3]

5展示使用 切片

>>> my_numbers = (1, 1, 2, 3, 5, 8, 13, 21)

>>> my_numbers[2:5]

(2, 3, 5)

>>> my_numbers[:3]

(1, 1, 2)

>>> my_numbers[3:]

(3, 5, 8, 13, 21)

>>> my_numbers[::]

(1, 1, 2, 3, 5, 8, 13, 21)

>>> my_numbers[1:7:2]

(1, 3, 8)

>>> interval = slice(1, 7, 2)

>>> my_numbers[interval]

(1, 3, 8)

>>> interval = slice(None, 3)

>>> my_numbers[interval] == my_numbers[:3]

True创建自定义序列

想要实现一个自定义的序列类,在类中实现这两个魔术方法即可: __getitem__ 和 __len__。

实现的手段有两种:继承 和 封装。

封装:

class Items:

def __init__(self, *values):

self._values = list(values)

def __len__(self):

return len(self._values)

def __getitem__(self, item):

return self._values.__getitem__(item)

继承:

class UserItems(collections.UserList):

pass

Context Managers

这里记录实现 ContextManager的三种方式。直接在类中实现 __enter__ 和 __exit__

def stop_service():

run("systemctl stop service")

def start_service():

run("systemctl start service")

class ServiceHandler:

def __enter__(self):

stop_service()

return self

def __exit__(self, exc_type, ex_value, ex_traceback):

start_service()

2. 调用contextlib里面的contextmanager装饰器

import contextlib

def stop_service():

run("systemctl stop service")

def start_service():

run("systemctl start service")

@contextlib.contextmanager

def service_handler():

stop_service()

yield

start_service()

3. 自定义装饰器

import contextlib

def stop_service():

run("systemctl stop service")

def start_service():

run("systemctl start service")

class Servicehandler_Decorator(contextlib.ContextDecorator):

def __enter__(self):

stop_service()

def __exit__(self, ext_type, ex_value, ex_traceback):

start_service()

Properties

对于 python 类内属性,如果想要定义属性为私有,更 Pythonic 的做法的使用单下划线,尽量不要使用双下划线。同时尽量使用 Properties 装饰器来为类里面的私有属性提供统一的访问接口。

import re

EMAIL_FORMAT = re.compile(r"[^@]+@[^@]+\.[^@]+")

def is_valid_email(potentially_valid_email: str):

return re.match(EMAIL_FORMAT, potentially_valid_email) is not None

class User:

def __init__(self, username):

self.username = username

self._email = None

@property

def email(self):

return self._email

@email.setter

def email(self, new_email):

if not is_valid_email(new_email):

raise ValueError(

f"Can't set{new_email}as it's not a valid email"

)

self._email = new_email

上面代码使用 property 装饰器修饰操作私有属性 email 的方法,使得该方法同时成为了外部接口,可以在外部定义这个私有变量,并且在接收之前使用了 is_valid_email 方法进行了校验。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值