文章来源:http://blog.csdn.net/qq_26656329/article/details/78427515
对于这些规范仁者见仁智者见智,我就有很多没遵守的,但是知道这些始终是好的。
原文
# 缺少任何一个就会有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
# 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'
def adder(n):
num = 0
while num < n:
yield num
num += 1
return num #Noncompliant
# 我测试了一下print(adder(10)) 返回值是:
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
# NONCOMPLIANT CODE EXAMPLE
exec 'print 1' # Noncompliant
# COMPLIANT SOLUTION
exec('print 1')
# 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
# 我知道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
# 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
# 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
# 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通常是表明这段代码有问题,但是开发者不想现在处理,又怕忘了所以就用到这个标签
# 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
# 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"
# NONCOMPLIANT CODE EXAMPLE
print '1' # Noncompliant
# COMPLIANT SOLUTION
print('1')
# 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)
# 原因以下有几点
# 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.
# 嵌套层次不超过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.
# 注释里面应该包含关于修复和完成哪些内容的信息
# 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
完成的单元测试是没有用的代码,要么重新测试、要么删除
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.
这个不太理解、