假如你是一个pythoner,你可以忍受下面的这段代码么?(当然,这是我为了举例乱写的,现实中应该没人这么写)
class Person1:
def __init__(self, BALL):
self.eatFood()
self.drink_water()
self.ball = BALL
self.PlayBall(self.ball)
def eatFood(self):
print("eat_food")
def drink_water(self):
print("Drink_water")
def PlayBall(self, Ball):
content = "i'm play {}".fomat(Ball)
print(content)
好吧,估计你也会看不下去,今天就来聊聊,python的编程风格。
本文参考的是 Google 版本的 Python 编程风格。
原文地址:https://google.github.io/styleguide/pyguide.html
原文实在是太长了,下面我就走马观花的介绍一下,假如感兴趣的,可以自行查看原文。
01、遵循pylint
pylint是一个检查python编程风格的工具,要求代码要通过pylint检测。
一般的IDE工具,比如Pycharm、VSCode,都有或者可安装pylint插件。
02、命名
函数名称,变量名称和文件名应具有描述性;避开缩写。
特别是,请勿使用项目外部读者不清楚或不熟悉的缩写,也不要通过删除单词中的字母来进行缩写。
龟叔要求的命名法则
Type | Public | Internal |
包名 | lower_with_under | |
模块名 | lower_with_under | _lower_with_under |
类名 | CapWords | _CapWords |
异常名 | CapWords | |
函数名 | lower_with_under() | _lower_with_under() |
全局/类常量 | CAPS_WITH_UNDER | _CAPS_WITH_UNDER |
全局/类变量 | lower_with_under | _lower_with_under |
实例变量 | lower_with_under | _lower_with_under (protected) |
方法名 | lower_with_under() | _lower_with_under() (protected) |
方法/函数 参数 | lower_with_under | |
本地变量 | lower_with_under |
应该避免的名称:
(1)避免单个字符的名称,异常“e”除外
YES
name = "小明"
NO
n = "小明"
(2)避免任何程序包/模块名称中的破折号()
YES
文件命名:test_2020_02_05.py
NO
文件命名:test-2020-02-05.py
(3)避免双下划线(__)包裹的变量名称(由python保留)
YES
age = 27
NO
__age__ = 27
03、True 和 False
在使用判断语句时,尽量使用“隐式假”。
在Python中,0, None, [], {}, ' '在布尔值上下文中,值都为 False。
使用Python布尔值的条件更易于阅读且不易出错。在大多数情况下,运行速度也更快。
YES
if not users:
print('no users')
if foo == 0:
self.handle_zero()
if i % 10 == 0:
self.handle_multiple_of_ten()
def f(x=None):
if x is None:
x = []
NO
if len(users) == 0:
print('no users')
if foo is not None and not foo:
self.handle_zero()
if not i % 10:
self.handle_multiple_of_ten()
def f(x=None):
x = x&nbs***bsp;[]
04、分号
不要用分号终止行,也不要使用分号在同一行上放置两个语句。
05、单行语句长度
最大行长度为80个字符,以下几种情况除外:
-
长 import 语句。
-
注释中的URL,路径名或长标记。
-
长字符串模块级别的常量不包含空格,这些常量不方便在URL或路径名等行之间进行拆分。
-
Pylint禁用注释。(如:# pylint: disable=invalid-name)
除非with需要三个或更多上下文管理器的语句,否则不要使用反斜线继续。
可利用括号隐式分割。
YES
foo_bar(self, width, height, color='black', design=None, x='foo',
emphasis=None, highlight=0)
if (width == 0 and height == 0 and
color == 'red' and emphasis == 'strong'):
YES
x = ('This will build a very long long '
'long long long long long long string')
YES
# See details at
# http://www.example.com/us/developer/documentation/api/content/v2.0/csv_file_name_extension_full_specification.html
NO
# See details at
# http://www.example.com/us/developer/documentation/api/content/\
# v2.0/csv_file_name_extension_full_specification.html
06、缩进
代码块缩进4个空格。
切勿使用制表符或将制表符和空格混用。
07、空行
import语句下面接两个空行
import os
def Xxx():
pass
方法定义之间有一个空行
def add():
pass
def multiplication():
pass
class 与 def 之间,有一个空行
class Person:
def eat(self):
pass
08、空格
括号,方括号或大括号内没有空格。
YES
spam(ham[1], {eggs: 2}, [])
NO
spam( ham[ 1 ], { eggs: 2 }, [ ] )
逗号,分号或冒号前没有空格;逗号,分号或冒号后有空格。
YES
if x == 4:
print(x, y)
x, y = y, x
NO
if x == 4 :
print(x , y)
x , y = y , x
以下运算符两侧各有一个空格
赋值运算符(=)
比较运算符(==, <, >, !=, <>, <=, >=, in, not in, is, is not)
布尔值(and, or, not)
算术运算符(+,-,*,/,//,%,**,@)
YES
x == 1
NO
x<1
= 传递关键字参数或定义默认参数值时,切勿使用空格;
但有一个例外:当存在类型注释时,请=在默认参数值的周围使用空格。
YES
def complex(real, imag=0.0): return Magic(r=real, i=imag)
def complex(real, imag: float = 0.0): return Magic(r=real, i=imag)
NO
def complex(real, imag = 0.0): return Magic(r = real, i = imag)
def complex(real, imag: float=0.0): return Magic(r = real, i = imag)
不要使用空格作为连续的行上垂直对齐的标记,
因为它会造成维护负担(适用于:,#,=,等)
YES
foo = 1000 # comment
long_name = 2 # comment that should not be aligned
dictionary = {
'foo': 1,
'long_name': 2,
}
NO
foo = 1000 # comment
long_name = 2 # comment that should not be aligned
dictionary = {
'foo' : 1,
'long_name': 2,
}
09、类
大体上和函数格式一致,以下是标准的书写格式范例:
class SampleClass(object):
"""Summary of class here.
Longer class information....
Longer class information....
Attributes:
likes_spam: A boolean indicating if we like SPAM or not.
eggs: An integer count of the eggs we have laid.
"""
def __init__(self, likes_spam=False):
"""Inits SampleClass with blah."""
self.likes_spam = likes_spam
self.eggs = 0
def public_method(self):
"""Performs operation blah."""
10、字符串
使用format方法或%运算符格式化字符串,避免使用+或+=拼接字符串
YES
x = a + b
x = '%s, %s!' % (imperative, expletive)
x = '{}, {}'.format(first, second)
x = 'name: %s; score: %d' % (name, n)
x = 'name: {}; score: {}'.format(name, n)
x = f'name: {name}; score: {n}' # Python 3.6+
NO
x = '%s%s' % (a, b) # use + in this case
x = '{}{}'.format(a, b) # use + in this case
x = first + ', ' + second
x = 'name: ' + name + '; score: ' + str(n)
11、引入模块
引包顺序:
先引入标准库,
再引入三方库,
最后引入自己代码的库。
import collections
import queue
import sys
from absl import app
from absl import flags
import bs4
import cryptography
import tensorflow as tf
from book.genres import scifi
from myproject.backend.hgwells import time_machine
from myproject.backend.state_machine import main_loop
from otherproject.ai import body
from otherproject.ai import mind
from otherproject.ai import soul
# Older style code may have these imports down here instead:
#from myproject.backend.hgwells import time_machine
#from myproject.backend.state_machine import main_loop
12、函数长度
偏爱小型且专注的功能。
函数长度没有硬性限制。如果一个函数超过40行,请考虑是否可以在不破坏程序结构的情况下将其分解。
关于作者
github:https://github.com/GitDzreal93/dev-tester
微信公众号:测试开发guide