Python 标准

文章来源:http://blog.csdn.net/qq_26656329/article/details/78427515

对于这些规范仁者见仁智者见智,我就有很多没遵守的,但是知道这些始终是好的。

原文


  • 定义exit函数时别忘记传递self, type, value 和 traceback.
# 缺少任何一个就会有TypeError: __exit__() takes 3 positional arguments but 4 were given
class MyClass:
    def __enter__(self):
        pass
    def __exit__(self, exc_type, exc_val):  # NONCOMPLIANT CODE EXAMPLE
        pass

    def __exit__(self, exc_type, exc_val, traceback):  # COMPLIANT SOLUTION
        pass

  • init函数不应该有返回值
# NONCOMPLIANT CODE EXAMPLE
class MyClass(object):
    # __init__方法不应该有返回值
    def __init__(self):
        self.message = 'Hello'
        return self
# TypeError: __init__() should return None, not 'MyClass'

# COMPLIANT SOLUTION
class MyClass(object):
    def __init__(self):
        self.message = 'Hello'

  • yield和return不能在同一个函数中使用,不然会引起报错SyntaxError
def adder(n):
     num = 0
     while num < n:
         yield num
         num += 1
     return num  #Noncompliant
# 我测试了一下print(adder(10)) 返回值是:<generator object adder at 0x7f5d03e0ee60>

  • yield和return不能在函数外使用,不然会引起报错SyntaxError
class MyClass: 
    while True:
        return False #Noncompliant
# SyntaxError: 'return' outside function

  • 输出带单引号的字符串
# NONCOMPLIANT CODE EXAMPLE
return `num`  # Noncompliant

# COMPLIANT SOLUTION
return repr(num)

  • 函数名不应该和属性名相同
# NONCOMPLIANT CODE EXAMPLE
class SomeClass:
    lookUp = false
    def lookup():       # Non-compliant; method name differs from field name only by capitalization
        pass

# COMPLIANT SOLUTION
class SomeClass:
    lookUp = false
    def getLookUp():
        pass
# 测试
class MyClass:

    @staticmethod
    def MyClass():
        print(5555)

MyClass().MyClass()
# 5555

  • 尽量避免使用exec函数,python3使用exec()函数
# NONCOMPLIANT CODE EXAMPLE
exec 'print 1' # Noncompliant

# COMPLIANT SOLUTION
exec('print 1')

  • break和continue应使用在循环内
# NONCOMPLIANT CODE EXAMPLE
narg=len(sys.argv)
if narg == 1:
    print('@Usage: input_filename nelements nintervals')
    break

# COMPLIANT SOLUTION
if narg == 1:
    print('@Usage: input_filename nelements nintervals')
    sys.exit()

  • 自定义的函数不应该过于复杂
复杂性是一个衡量函数的可控性和理解难度,高复杂的函数很难维护
Cognitive Complexity
http://redirect.sonarsource.com/doc/cognitive-complexity.html

  • 不要import重复的模块
# 我知道pycharm会有一个黄色提示Unused import statement,第一个引入的sys不会被使用
import sys
import sys
print('hi')
sys.exit()

  • 不要使用<>来作为不等于
# NONCOMPLIANT CODE EXAMPLE
return a <> b # Noncompliant

# COMPLIANT SOLUTION
return a != b

  • 不要使用递增或递减运算符
# NONCOMPLIANT CODE EXAMPLE
++x # Noncompliant

# COMPLIANT SOLUTION
x += 1

# 测试
num = 0
for i in range(0, 10):
    print(num++)
# SyntaxError: invalid syntax
num = 0
for i in range(0, 3):
    print(++num)
# 0
# 0
# 0
num = 0
for i in range(0, 10):
    num += i
print(num)
# 45

  • if结构中不应该有相同的逻辑,如果有请合并逻辑
# NONCOMPLIANT CODE EXAMPLE
if 0 <= a < 10:
    do_the_thing()
elif 10 <= a < 20:
    do_the_other_thing()
elif 20 <= a < 50:
    do_the_thing()  # Noncompliant; duplicates first condition
else:
    do_the_rest()
b = 4 if a > 12 else 4

# COMPLIANT SOLUTION
if (0 <= a < 10) or (20 <= a < 50):
    do_the_thing()
elif 10 <= a < 20:
    do_the_other_thing()
else:
    do_the_rest()
b = 4

# or
if 0 <= a < 10:
    do_the_thing()
elif 10 <= a < 20:
    do_the_other_thing()
elif 20 <= a < 50:
    do_the_third_thing()
else:
    do_the_rest()
b = 8 if a > 12 else 4
# 这里有个例外,我理解的是break除了在循环中不应该出现。怎么理解智者见智吧
# Blocks in an if chain that contain a single line of code are ignored, as are blocks in a switch statement that contain a single line of code with or without a following break.
# 自己写的例子
a = 10
if a == 10:
    print(a)
    break   # 这里会报错 'break' outside loop

for i in range(0, a):
    print(i)
    if i == 6:
        break

  • if 判断不应该有同样的判断条件
# NONCOMPLIANT CODE EXAMPLE
if param == 1:
    openWindow()
elif param == 2:
    closeWindow()
elif param == 1:            # Noncompliant
    moveWindowToTheBackground()

# COMPLIANT SOLUTION
if param == 1:
    openWindow()
elif param == 2:
    closeWindow()
elif param == 3:        
    moveWindowToTheBackground()

  • 检查删除无效或未调用的代码
CERT, MSC12-C. 删除无效或未调用的代码
https://www.securecoding.cert.org/confluence/x/NYA5
CERT, MSC12-CPP. 删除无效的代码
https://www.securecoding.cert.org/confluence/x/SIIyAQ

  • return后面不要有其它代码
# NONCOMPLIANT CODE EXAMPLE
def fun(a):
    i = 10
    return i + a       # Noncompliant 
    i += 1             # this is never executed

# COMPLIANT SOLUTION
def fun(a):
    i = 10
    return i + a

  • 定义函数名不应该包含类名,容易混淆
# NONCOMPLIANT CODE EXAMPLE
class Foo: 
    foo = '' 

    def getFoo(self):
        ...

foo = Foo()
foo.getFoo() # 这个返回值是什么?这个类吗?

# COMPLIANT SOLUTION
class Foo:
    name = ''

    def getName(self):
        ...

foo = Foo()
foo.getName()   # 这个很容易明白是获取类属性

  • 应该禁止变量自赋值
# 重新赋值是错误的,如有必要或多余的请删除这个变量
# NONCOMPLIANT CODE EXAMPLE
name = name

# COMPLIANT SOLUTION
name = other.name

# CERT, MSC12-C.
# https://www.securecoding.cert.org/confluence/x/NYA5  # 删除无效或未调用的代码
# CERT, MSC12-CPP.
# https://www.securecoding.cert.org/confluence/x/SIIyAQ  # 删除无效的代码

  • 函数名应该符合命名规范
# 函数名命名长度在2-30位之间,单词之间用_隔开,函数名开头字母开头,单词不要使用大写开头
# 默认的函数吗正则^[a-z_][a-z0-9_]{2,30}
# NONCOMPLIANT CODE EXAMPLE
def MyFunction(a,b):
    ...

# COMPLIANT SOLUTION
def my_function(a,b):
    ...

  • ‘FIXME’标签使用
# FIXME通常是表明这段代码有问题,但是开发者不想现在处理,又怕忘了所以就用到这个标签
# NONCOMPLIANT CODE EXAMPLE
def divide(numerator, denominator):
    return numerator / denominator              # FIXME denominator value might be 0
# 

  • 删除多余的括号
# NONCOMPLIANT CODE EXAMPLE
return ((3))        # Noncompliant
return ((x + 1))    # Noncompliant
x = ((y / 2)) + 1   # Noncompliant

# COMPLIANT SOLUTION
return 3
return (3)
return x + 1
return (x + 1)
x = y / 2 + 1
x = (y / 2) + 1

  • 合并if判断
# NONCOMPLIANT CODE EXAMPLE
if condition1:
    if condition2:
        # ...

# COMPLIANT SOLUTION
if condition1 and condition2:
    # ...

  • 不要存在没有逻辑的代码块
# 代码块中有注释代码的话,这个代码块不是空的
# NONCOMPLIANT CODE EXAMPLE
for i in range(3):
    pass

  • 函数、匿名函数、回调参数不应该有太多
# 保持在4个以内最好
# NONCOMPLIANT CODE EXAMPLE
def do_something(param1, param2, param3, param4, param5):
    ...

# COMPLIANT SOLUTION
def do_something(param1, param2, param3, param4):
    ...

  • 代码不应该被注释掉
# 没有用到的代码片段请把它删掉,如有需要请在版本库中查找
# 觉得这个看个人习惯吧,我就懒的去翻代码库,经常注释代码
# MISRA C:2004, 2.4 - Sections of code should not be "commented out".
# MISRA C++:2008, 2-7-2 - Sections of code shall not be "commented out" using C-style comments.
# MISRA C+:2008, 2-7-3 - Sections of code should not be "commented out" using C+ comments.
# MISRA C:2012, Dir. 4.4 - Sections of code should not be "commented out"

  • 不应该使用print语句,因为Python3中已经把print删除了,请使用内置函数print()
# NONCOMPLIANT CODE EXAMPLE
print '1'  # Noncompliant
# COMPLIANT SOLUTION
print('1') 

  • 没有必要不要使用pass
# NONCOMPLIANT CODE EXAMPLE
    def __init__(self, log="", who="", date=0, files=[]):
        self.log = log
        self.files = files
        self.who = who
        self.date = date
        pass    # Noncompliant

    def lookup():
        pass    # Compliant; method can't be empty

# COMPLIANT SOLUTION
    def __init__(self, log="", who="", date=0, files=[]):
        self.log = log
        self.files = files
        self.who = who
        self.date = date

    def lookup():
        pass

  • 删除未使用的变量
# 声明一个变量而没有使用它,请把它删掉,从而提高可维护性
# NONCOMPLIANT CODE EXAMPLE
def hello(name):
    message = "Hello " + name # Noncompliant
    print(name)

# COMPLIANT SOLUTION
def hello(name):
    message = "Hello " + name
    print(message)

  • 不要硬编码去获取IP地址
# 原因以下有几点
# 1.动态的ip地址需要重新编译
# 2.代码环境的不同所使用的地址也不同
# 3.通过反编译从而泄露敏感地址
# 4.忘了修改的话,会把测试环境的地址带到生产环境上
# NONCOMPLIANT CODE EXAMPLE
ip = '127.0.0.1'
sock = socket.socket()
sock.bind((ip, 9090))
# COMPLIANT SOLUTION
ip = config.get(section, ipAddress)
sock = socket.socket()
sock.bind((ip, 9090))
# 不要硬编码敏感信息
# https://www.securecoding.cert.org/confluence/x/qQCHAQ

  • 变量名和函数参数名应该符合规范
# 变量名和函数参数名相同时会产生错误
# 循环变量将会忽略这个问题
for i in range(limit):  # Compliant
    print(i)

  • 变量名称应该符合规范
# 匹配正则 ^[_a-z][_a-z0-9]*$
# NONCOMPLIANT CODE EXAMPLE
class MyClass:
    myField = 1

# COMPLIANT SOLUTION
class MyClass:
    my_field = 1

  • 类名应该符合规范
# NONCOMPLIANT CODE EXAMPLE
# 匹配正则 ^[A-Z][a-zA-Z0-9]*$
class myClass:
    ...

# COMPLIANT SOLUTION
class MyClass:
    ...

函数名应该符合规范

# 函数名长度在30位之内
# NONCOMPLIANT CODE EXAMPLE
# 匹配正则 ^[a-z_][a-z0-9_]{2,30}$
class MyClass:
    def MyMethod(a,b):
        ...

#COMPLIANT SOLUTION
class MyClass:
    def my_method(a,b):
        ...

  • 单元测试没有通过的应该尽快修复
Test failures or errors generally indicate that regressions have been introduced. Those tests should be handled as soon as possible to reduce the cost to fix the corresponding regressions.

  • 版本分支应该通过单元测试在合并到主分支
An issue is created on a file as soon as the branch coverage on this file is less than the required threshold. It gives the number of branches to be covered in order to reach the required threshold.

  • 一个类不要太复杂以便于可维护
The cyclomatic complexity of a class should not exceed a defined threshold. Complex code can perform poorly and will in any case be difficult to understand and therefore to maintain.

  • 一个函数不要太复杂以便于可维护
The Cyclomatic Complexity of functions should not exceed a defined threshold. Complex code may perform poorly and can be difficult to test thoroughly.

  • 单元测试覆盖全部代码块
An issue is created on a file as soon as the line coverage on this file is less than the required threshold. It gives the number of lines to be covered in order to reach the required threshold.

  • if、for、while、try、with不应该嵌套太多层
# 嵌套层次不超过3层
# NONCOMPLIANT CODE EXAMPLE
if condition1:           # Compliant - depth = 1
    # ...
    if condition2:         # Compliant - depth = 2
        # ...
        for i in range(10):  # Compliant - depth = 3, not exceeding the limit
            # ...
            if condition4:     # Non-Compliant - depth = 4
                if condition5:   # Depth = 5, exceeding the limit, but issues are only reported on depth = 4
                    # ...

  • “\”只能作为愿意字符使用

# NONCOMPLIANT CODE EXAMPLE
s = "Hello \world."
t = "Nice to \ meet you"
u = "Let's have \ lunch"

# COMPLIANT SOLUTION
s = "Hello world."
t = "Nice to \\ meet you"
u = r"Let's have \ lunch"  # raw string

  • 定义注释
# NONCOMPLIANT CODE EXAMPLE
def my_function(a,b):

# COMPLIANT SOLUTION
def my_function(a,b):
      """Do X"""

  • 一个文件不应该太过复杂,一个复杂的文件应该被分为多份
Most of the time, a very complex file breaks the Single Responsibility Principle and should be re-factored into several different files.

  • 一个文件不应该有太多行代码
A source file that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain. Above a specific threshold, it is strongly advised to refactor it into smaller pieces of code which focus on well defined tasks. Those smaller files will not only be easier to understand but also probably easier to test.

  • 一行代码不应该过长、过长请换行,最好不要出现横向滚动条
Having to scroll horizontally makes it harder to get a quick overview and understanding of any piece of code.

  • 一个函数不应该声明太多返回值
# 声明的返回值不应该超出3个
# 声明的返回值太多会增加函数的复杂性,遇到返回语句时执行流程就会中断,让理解函数的逻辑变得复杂
# NONCOMPLIANT CODE EXAMPLE

def fun():          # Noncompliant as there are 4 return statements
    if condition1:
        return True
    elif condition2:
        return False
    else:
        return True
    return False

  • 一行代码不应该有多个语句
# 为了增加代码的可读性不要在一行写多个语句代码
# NONCOMPLIANT CODE EXAMPLE
if (True): print("hello")

# COMPLIANT SOLUTION
if (True): 
    print("hello")

  • 当代码解析失败记录下报错文件,以便找出解析失败原因
When the Python parser fails, it is possible to record the failure as a violation on the file. This way, not only it is possible to track the number of files that do not parse but also to easily find out why they do not parse.

  • 行代码后面不应该有空格
Trailing whitespaces are simply useless and should not stay in code. They may generate noise when comparing different versions of the same file.
If you encounter issues from this rule, this probably means that you are not using an automated code formatter - which you should if you have the opportunity to do so.

  • 注意字母和数字混淆
# NONCOMPLIANT CODE EXAMPLE
return 10l  // Noncompliant; easily confused with one zero one

# COMPLIANT SOLUTION
return 10L

  • 尽量使用新版本的声明方式来声明类
# 如果可以建议使用父类的声明方式创建新的类
# NONCOMPLIANT CODE EXAMPLE
class MyClass():
    pass

# COMPLIANT SOLUTION
class MyClass(object):
    pass

  • 某些表达式不应使用括号
# Parentheses are not required after the assert, del, elif, except, for, if, in, not, raise, return, while, and yield keywords, and using them unnecessarily impairs readability. They should therefore be omitted.
# NONCOMPLIANT CODE EXAMPLE
x = 1
while (x < 10):
    print "x is now %d" % (x)
    x += 1

# COMPLIANT SOLUTION
x = 1
while x < 10:
    print "x is now %d" % (x)
    x += 1

  • 不需要实例的类、函数应该是静态的
# 类方法将类作为隐式第一个参数接收, 就像实例方法接收实例一样。静态方法不接收隐式第一个参数。
# NONCOMPLIANT CODE EXAMPLE
class Utilities:
    def do_the_thing(self, arg1, arg2, ...):  # Noncompliant
        #...

# COMPLIANT SOLUTION
class Utilities:
    @classmethod
    def do_the_thing(cls, arg1, arg2, ...):
        #...

# or
class Utilities:
    @staticmethod
    def do_the_thing(arg1, arg2, ...):
        #...

# EXCEPTIONS
# Methods which raise or may raise a NotImplementedError are ignored.

  • 跟踪自己的”TODO”和”FIXME”注释,及时处理并予以删除。
# 注释里面应该包含关于修复和完成哪些内容的信息
# NONCOMPLIANT CODE EXAMPLE
# TODO 

# COMPLIANT SOLUTION
# TODO(ganncamp) per the business partners, more checks needed

  • 注释写在代码上一行
# 自动格式化代码无法正确的处理这样的注释
# NONCOMPLIANT CODE EXAMPLE
a = b + c   # This is a trailing comment that can be very very long 

# COMPLIANT SOLUTION
# This very long comment is better placed before the line of code
a = b + c 

  • 文件最后一行应该是一个空白行
# 不加空白行有时会有以下提示No newline at end of file

  • 模块名称应符合规范
Shared coding conventions allow teams to collaborate effectively. For that reason, module names should conform to a defined standard.
参考
CERT, MSC09-CPP. https://www.securecoding.cert.org/confluence/x/P4IyAQ
CERT, MSC09-C. https://www.securecoding.cert.org/confluence/x/lQAl

  • 应该删除或修复已完成的单元测试
完成的单元测试是没有用的代码,要么重新测试、要么删除

  • Track instances of below-threshold comment line density
An issue is created on a file as soon as the density of comment lines on this file is less than the required threshold. The number of comment lines to be written in order to reach the required threshold is provided by each issue message.
这个不太理解、
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值