讲 OOP 和 metaclass 的部分比较好

masterplan

其他部分(并发, 模块, 部署)大部分都了解, 更愿意看一下 OOP 的想法. 在这里稍微记一下.

尽量使用异常来表示特殊情况, 而不要 return None

现在看, 有两种比较棘手的情况:

(1) 有时候一个方法里涉及数个含网络请求(which means 必须考虑失败)的调用, 会写成这样:

def call0():

try:

call1()

except:

handle1()

try:

call2()

except:

handle2()

挺啰嗦的. 另一种方式是不管了:

def call0():

call1()

call2()

扔给上级. 问题是选哪一种不好把握: 第一种有些出错没法 handle(网络请求失败, 重试还是失败, 怎么办?), 很多情况下 handle() 里还是 raise, 会想索性不管了, 就写第二种反正上级必须 handle 住.

(2) 不能处理的, 用 exception 明确告知上级. 有些问题报给上级, 上级觉得"这也是我的异常情况", 然后又 raise, 导致一长串的 try .. except. 目前还没看到好的解决办法.

闭包中使用外部作用域变量

Py3 的 nonlocal 专门来做这一点(注意和 global 不一样, 专门为闭包定义的), Py2 通过 li...

显示全文

其他部分(并发, 模块, 部署)大部分都了解, 更愿意看一下 OOP 的想法. 在这里稍微记一下.

尽量使用异常来表示特殊情况, 而不要 return None

现在看, 有两种比较棘手的情况:

(1) 有时候一个方法里涉及数个含网络请求(which means 必须考虑失败)的调用, 会写成这样:

def call0():

try:

call1()

except:

handle1()

try:

call2()

except:

handle2()

挺啰嗦的. 另一种方式是不管了:

def call0():

call1()

call2()

扔给上级. 问题是选哪一种不好把握: 第一种有些出错没法 handle(网络请求失败, 重试还是失败, 怎么办?), 很多情况下 handle() 里还是 raise, 会想索性不管了, 就写第二种反正上级必须 handle 住.

(2) 不能处理的, 用 exception 明确告知上级. 有些问题报给上级, 上级觉得"这也是我的异常情况", 然后又 raise, 导致一长串的 try .. except. 目前还没看到好的解决办法.

闭包中使用外部作用域变量

Py3 的 nonlocal 专门来做这一点(注意和 global 不一样, 专门为闭包定义的), Py2 通过 list 修改闭包的变量. 感觉还是不甚优雅? 为什么不像 Scheme 那样默认闭包内数据可写呢? 有空看看.

用辅助类维护程序状态

平时用到的一些状态装在结构繁杂的字典里, 每次更新/解析需要用两层以上的循环. 这种复杂度统一放在辅助类里比较好. 不想每次都回忆字典的哪一层放了什么东西.

接口接收定义了 __call__() 方法的简单类

传入函数的接口可以通过这种方法传入类的实例, 从里面取东西出来:

example(func, args) => i = Class(), example(i, args)

当然

example(func, args) => example(i.method, args) 也一样, 不过看着方便点.

通过 @classmethod 多态构建对象

基类这么写:

class C(object):

@classmethod

def builder(cls, args):

pass

给一组派生类提供统一的构建器. 这样对这组派生类可以这么写:

def func(c, args):

i = c.builder()

MixIn

严格来说 MixIn 是不提供成员变量的, 也就没有 __init__. ToDictMixIn 这种应该蛮有用.

Public, Protected and Private

Python 类实际只有 Public 和 Private, 然后根据 "We are adults" 原则, 尽量避免 private.

collections.abc 实现自定义容器类型

制造自己的列表, 字典.

@property

重构时为成员添加行为很有用, 也别滥用了

__get__, __set__

所谓 descriptor. 就是只具有一个成员变量的类.

getattr, setattr, __getattr__, __setattr__, __getattribute__

__getattr__ 不存在属性读 hook

__getattribute__ 所有属性读 hook

__setattr__ 所有属性写 hook

这几个拿来面人应该蛮好用

通过 metaclass 验证子类

因为 metaclass 的 __new__ 是子类创建 hook. 它不通过就没法创建子类(可用单例模式).

0
0

查看更多豆瓣高分好书

回应(0)

添加回应

推荐Effective Python的豆列

了解更多图书信息

值得一读

    豆瓣
    我们的精神角落
    免费下载 iOS / Android 版客户端