pythonic之路(一)

pythonic之路—-编写简洁清晰python代码(一)

一、if中不要直接将语句与TrueFalseNone做比较

python中隐含为False的对象:

None

False

数值0(不是字符"0"

空容器,比如空list x=[]、空tuple x=()、空dict x={}、空str x=""

其余的则隐含为True

尽量避免用如下语法if foo == Trueif x == 0if len(bar) == 0,应替换为if fooif not xif not bar

但是,如果一个程序的关键字参数默认值为None,代码需要判断输入是否为None,则必须显式的与None比较,即

def foo(x=None):
    if x is not None:
    pass

假如写为

def foo(x=None):
    if x:
    pass

那么x=0也被排除在外,如果参数x是一个序列的指标(index)则0显然是其中一个而不应该被排除。

同时,要记住,与None作比较时用isis not,不要用==

所以,None是个例外,对于其他的条件判断,直接用python隐含的TrueFalse来做比较,而不是==

二、尽量不要用可变对象(比如list、dict)作为函数的默认参数

因为可变对象会将实参累积起来,导致随后的调用出现问题。可用None作为默认值。

问题代码:

def foo_(foo, bar=["bar"]):
    bar.append(foo)
    return bar
print(foo_(1))#输出['bar', 1]
print(foo_(1))#输出['bar', 1, 1]
print(foo_(1))#输出['bar', 1, 1, 1]

改进代码:

def foo_1(foo, bar=None):
    if bar is None:
        bar = ["bar"]
    bar.append(foo)
    return bar
print(foo_1(1))#输出['bar', 1]
print(foo_1(1))#输出['bar', 1]
print(foo_1(1))#输出['bar', 1]

总的来说,要在函数里重新初始化形参,这样每次调用时都是以初始化的形参来接收实参,从而避免了累加。这对初学者来说可能是个陷阱,但老司机一般不会犯这样的错。

三、用*表示list的剩余元素

>>>x = ["a", "b", "c", "d", "e"]
>>>(f, s, *r) = x
f = "a"
s = "b"
r = ["c", "d", "e"]
>>>(f, *m, l) = x
f = "a"
s = "e"
m = ["b", "c", "d"]

四、通过字典dict.get给变量提供默认值

字典方法mydict.get(k,d)实现了一个条件判断功能。return mydict[k] if k in mydict, else return d

一个原理验证例子。

>>>x = ["a", "b", "c", "d", "e"]
>>>z = dict((k,v) for k,v in zip(x,range(6)))
>>>z1 = z.get("a",10)#z1 = 0
>>>z1 = z.get("x",10)#z1 = 10

一个有点用处但语法啰嗦的例子。

log_severity = None
if 'severity' in configuration:
    log_severity = configuration['severity']
else:
    log_severity = 'Info'

dict.get改进版。

log_severity = configuration.get('severity', 'Info')

五、用format函数格式化字符串

格式化字符串一般有三种方法,用“+”、用“%”、用“format函数”。

最糟糕的莫过于用“+”,语句冗长晦涩难懂(尤其当有一串字符需要格式化时);

用“%”稍微好一些,缺点是用变量格式作为占位符,完全与格式化的内容脱节,也难懂;

format直接使用命名的占位符,一看一目了然,清晰简洁。

def get_formatted_user_info(user):
#最糟的方式
    return 'Name: ' + user.name + ', Age: ' + str(user.age) + ', Sex: ' + user.sex
def get_formatted_user_info(user):
#不太好的方式
    return 'Name: %s, Age: %i, Sex: %c' % (user.name, user.age, user.sex)
def get_formatted_user_info(user):
#良好方式
    output = 'Name: {user.name}, Age: {user.age}, Sex: {user.sex}'.format(user=user)
    return output

六、如果有一个list,可用"".join(mylist)创建一个string

七、class受保护变量和私有变量

受保护变量以单下划线开始,比如self._id = id,受保护的意思是提示客户(client)不要直接使用它。

私有变量以双下划线开始,比如self.__id = id,私有的意思是提示子类没法直接调用该属性。

一定要记住,这只是程序员所遵循的一个传统而已,如果client真想一窥究竟,谁也没法阻止,实际上没有真正的隐私。但是要尊重开发人员的意图。

八、在class里定义一个魔法方法__str__,用于友好的打印instance信息。

class Point():
    def __init__(self, x, y, name):
        self.x = x
        self.y = y
        self._name = name
    def __str__(self):
        return "{}({})".format(self.__class__.__name__, self._name)

if __name__ == "__main__":
    p = Point(1,2,"two point")
    print(p)#显示Point(two point)

九、用set消除重复元素

集合的一个特性是唯一性,即没有重复的元素。相当于字典的键。

setIterableContainer的子类。所以可用于for循环,也可当做in语句的迭代对象。

y = ['bar', 1, 1, 2, 1, 1, 1, 1]
for s in set(y):
    print(s)#输出1,2,bar

集合可以很方便的用集合表达式(类似于列表表达式)来生成。

users_first_names = {user.first_name for user in users}

set包含了所有数学意义上集合的运算,比如并(A|B)、交(A&B)、差(A-B)、对称差(并集-交集A^B)。

可以通过交集求出经常上线的且正在活跃的用户。


啰嗦写法:

def get_both_popular_and_active_users():
    most_popular_users = get_list_of_most_popular_users()#存储用户名的list
    most_active_users = get_list_of_most_active_users()#存储用户名的list
    opular_and_active_users = []
    for user in most_active_users:
        if user in most_popular_users:
            popular_and_active_users.append(user)
    return popular_and_active_users

简洁写法:

def get_both_popular_and_active_users():
    return(set(get_list_of_most_active_users()) & set(get_list_of_most_popular_users()))

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(内容同步更新到微信公众号python数学物理,微信号python_math_physics
这里写图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值