• python 反模式


    不使用 pythonic 的循环:

    l = [1,2,3]
    
    #Bad
    for i in range(0,len(list)):
        le = l[i]
        print(i,le)
    
    #Good
    for i,le in enumerate(l):
        print(i,le)
    
    

    函数调用返回一个以上的变量类型

    #Bad
    
    def filter_for_foo(l):
        r = [e for e in l if e.find("foo") != -1]
        if not check_some_critical_condition(r):
            return None
        return r
    
    res = filter_for_foo(["bar","foo","faz"])
    
    if res is not None:
        #continue processing
        pass
    
    #Good
    
    def filter_for_foo(l):
        r = [e for e in l if e.find("foo") != -1]
        if not check_some_critical_condition(r):
            raise SomeException("critical condition unmet!")
        return r
    
    try:
        res = filter_for_foo(["bar","foo","faz"])
        #continue processing
    except SomeException:
        #handle exception
    
    

    循环永不终止

    
    #example:
    i = 0
    while i < 10:
        do_something()
        #we forget to increment i
    
    

    不使用 .iteritems() 遍历 dict 的键/值对.

    
    #Bad
    
    d = {'foo' : 1,'bar' : 2}
    
    for key in d:
        value = d[key]
        print("%s = %d" % (key,value))
    
    #Good
    
    for key,value in d.iteritems():
        print("%s = %d" % (key,value))
    
    

    不使用 zip() 遍历一对列表

    
    #Bad
    
    l1 = [1,2,3]
    l2 = [4,5,6]
    
    for i in range(l1):
        l1v = l1[i]
        l2v = l2[i]
        print(l1v,l2v)
    
    #Good
    
    for l1v,l2v in zip(l1,l2):
        print(l1v,l2v)
    
    

    Using "key in list" to check if a key is contained in a list.

    This is not an error but inefficient, since the list search is O(n). If possible, a set or dictionary
    should be used instead.

    Note: Since the conversion of the list to a set is an O(n) operation, it should ideally be done only once when generating the list.

    
    #Bad:
    
    l = [1,2,3,4]
    
    if 3 in l:
        pass
    
    #Good
    
    s = set(l)
    
    if 3 in s:
        pass
    
    

    在循环之后,不使用 'else'.

    
    #Bad
    
    found = False
    
    l = [1,2,3]
    
    for i in l:
        if i == 4:
            found = True
            break
    
    if not found:
        #not found...
        pass
    
    #Good
    
    for i in l:
        if i == 4:
            break
    else:
        #not found...
    
    

    对于dict,不使用.setdefault()设置初始值

    
    #Bad
    
    d = {}
    
    if not 'foo' in d:
        d['foo'] = []
    
    d['foo'].append('bar')
    
    #Good
    
    d = {}
    
    foo = d.setdefault('foo',[])
    foo.append(bar)
    
    

    对于dict,不使用.get()返回缺省值

    
    #Bad
    
    d = {'foo' : 'bar'}
    
    foo = 'default'
    if 'foo' in d:
        foo = d['foo']
    
    #Good
    
    foo = d.get('foo','default')
    
    

    使用map/filter而不是列表解析

    
    #Bad:
    
    values = [1,2,3]
    
    doubled_values = map(lambda x:x*2,values)
    
    #Good
    
    doubled_values = [x*2 for x in values]
    
    
    #Bad
    
    filtered_values = filter(lambda x:True if x < 2 else False,values)
    
    #Good
    
    filtered_values = [x for x in values if x < 2]
    
    

    不使用defaultdict

    
    #Bad
    
    d = {}
    
    if not 'count' in d:
        d['count'] = 0
    
    d['count']+=1
    
    #Good
    
    from collections import defaultdict
    
    d = defaultdict(lambda :0)
    
    d['count']+=1
    
    

    从一个函数中返回多个值时,不使用命名元组(namedtuple)

    命名元组可以用于任何正常元组使用的地方,但可以通过name访问value,而不是索引。这使得代码更详细、更容易阅读。

    
    #Bad
    
    def foo():
        #....
        return -1,"not found"
    
    status_code,message = foo()
    
    print(status_code,message)
    
    #Good
    
    from collections import namedtuple
    
    def foo():
        #...
        return_args = namedtuple('return_args',['status_code','message'])
        return return_args(-1,"not found")
    
    ra = foo()
    
    print(ra.status_code,ra.message)
    
    

    不使用序列的显式解包

    支持解包的序列有:list, tuple, dict

    
    #Bad
    
    l = [1,"foo","bar"]
    
    l0 = l[0]
    l1 = l[1]
    l2 = l[2]
    
    #Good
    
    l0,l1,l2 = l
    
    

    不使用解包一次更新多个值

    
    #Bad
    
    x = 1
    y = 2
    
    _t = x
    
    x = y+2
    y = x-4
    
    #Good
    
    x = 1
    y = 2
    
    x,y = y+2,x-4
    
    

    不使用'with'打开文件

    
    #Bad
    
    f = open("file.txt","r")
    content = f.read()
    f.close()
    
    #Good
    
    with open("file.txt","r") as input_file:
        content = f.read()
    
    

    要求许可而不是宽恕

    
    #Bad
    
    import os
    
    if os.path.exists("file.txt"):
        os.unlink("file.txt")
    
    #Good
    
    import os
    
    try:
        os.unlink("file.txt")
    except OSError:
        pass
    
    

    不使用字典解析

    
    #Bad
    
    l = [1,2,3]
    
    d = dict([(n,n*2) for n in l])
    
    #Good
    
    d = {n : n*2 for n in l}
    
    

    使用字符串连接,而不是格式化

    
    #Bad
    
    n_errors = 10
    
    s = "there were "+str(n_errors)+" errors."
    
    #Good
    
    s = "there were %d errors." % n_errors
    
    

    变量名包含类型信息(匈牙利命名)

    
    #Bad
    
    intN = 4
    strFoo = "bar"
    
    #Good
    
    n = 4
    foo = "bar"
    
    

    实现java风格的getter和setter方法,而不是使用属性。

    
    #Bad
    
    class Foo(object):
    
        def __init__(a):
            self._a = a
    
        def get_a(self):
            return a
    
        def set_a(self,value):
            self._a = value
    
    #Good
    
    class Foo(object):
    
        def __init__(a):
            self._a = a
    
        @property
        def a(self):
            return self._a
    
        @a.setter
        def a(self,value):
            self._a = value
    
    #Bad
    
    def calculate_with_operator(operator, a, b):
    
        if operator == '+':
            return a+b
        elif operator == '-':
            return a-b
        elif operator == '/':
            return a/b
        elif operator == '*':
            return a*b
    
    #Good
    
    def calculate_with_operator(operator, a, b):
    
        possible_operators = {
            '+': lambda a,b: a+b,
            '-': lambda a,b: a-b,
            '*': lambda a,b: a*b,
            '/': lambda a,b: a/b
        }
    
        return possible_operators[operator](a,b)
    
    #Bad
    
    
    class DateUtil:
        @staticmethod
        def from_weekday_to_string(weekday):
            nameds_weekdays = {
                0: 'Monday',
                5: 'Friday'
            }
    
            return nameds_weekdays[weekday]
    
    #Good
    
    def from_weekday_to_string(weekday):
        nameds_weekdays = {
            0: 'Monday',
            5: 'Friday'
        }
    
        return nameds_weekdays[weekday]
    
  • 相关阅读:
    SpringBoot多数据源动态切换数据源
    @ConfigurationProperties 在IDEA中出现红色波浪线问题
    springboot+mybatis实现动态切换数据源
    Spring Boot配置多个DataSource
    模拟测试 20190714
    暴力日记
    模拟测试20190707 [排序//划艇//放棋子]
    组合数学总结
    莫比乌斯专题总结
    AC自动机总结
  • 原文地址:https://www.cnblogs.com/hhh5460/p/5724530.html
Copyright © 2020-2023  润新知