PEP是Python Enhancement Proposal的缩写,翻译过来教"Python增强规范"。
Python的缩进其实可以写成很多种,Tab、双空格、四空格、空格和Tab混合等。而PEP 8规范要求,选择四个空格的缩进,不要使用Tab,更不要使用Tab和空格混着用。
第二个注意:每行最大长度限制在79个字符
Python中的空行对Python解释器的执行没有影响,但对阅读体验有很深刻的影响。
PEP 8规定,全局的类和函数的上方需要空两个空行,而类的函数之间需要空一个空行。
函数内部也可以使用空行,和英文的段落一样,用来区分不同的代码块,但最多空一行。
另外,Python本身允许把多行合并一行,使用分号隔开,但这是PEP 8不推荐的做法。
至于代码的尾部,每个代码文件的最后一行为空行,并且只有这一个空行。
函数的参数列表中,调用函数的参数列表中会出现逗号,逗号后要跟一个空格。
冒号经常被用来初始化字典,冒号后边也要跟着一个空格。
另外,Python中可以使用#进行单独注释,要在#后注释前加一个空格。
对于操作符,例 +, -, *, / … 在两边都要保留空格。不过与此对应,括号内的两端并不需要空格。
示例
def solve1(this_is_the_first_parameter, this_is_the_second_parameter, this_is_the_third_parameter, this_is_the_forth_parameter, this_is_the_fifth_parameter, this_is_the_sixth_parameter): return (this_is_the_first_parameter + this_is_the_second_parameter + this_is_the_third_parameter + this_is_the_forth_parameter + this_is_the_fifth_parameter + this_is_the_sixth_parameter) def solve2(this_is_the_first_parameter, this_is_the_second_parameter, this_is_the_third_parameter, this_is_the_forth_parameter, this_is_the_fifth_parameter, this_is_the_sixth_parameter): return this_is_the_first_parameter + this_is_the_second_parameter + this_is_the_third_parameter + \ this_is_the_forth_parameter + this_is_the_fifth_parameter + this_is_the_sixth_parameter (top_secret_func(param1=12345678, param2=12345678, param3=12345678, param4=12345678, param5=12345678).check() .launch_nuclear_missile().wait()) top_secret_func(param1=12345678, param2=12345678, param3=12345678, param4=12345678, param5=12345678).check() \ .launch_nuclear_missile().wait()可以通过两种方法优化代码
第一种通过括号来将国长的运算进行封装,此时虽然跨行,但是仍处于一个逻辑引用之下。函数调用也可以使用类似的方式,只需要用一对括号将其包裹起来。
第二种则是通过换行符来实现。
class Model(network.Network): def fit(self, x=None, y=None, batch_size=None, epochs=1, verbose=1, callbacks=None, validation_split=0., validation_data=None, shuffle=True, class_weight=None, sample_weight=None, initial_epoch=0, steps_per_epoch=None, validation_steps=None, validation_freq=1, max_queue_size=10, workers=1, use_multiprocessing=False, **kwargs): # Legacy support if 'nb_epoch' in kwargs: logging.warning( 'The `nb_epoch` argument in `fit` has been renamed `epochs`.') epochs = kwargs.pop('nb_epoch') if kwargs: raise TypeError('Unrecognized keyword arguments: ' + str(kwargs)) self._assert_compile_was_called() func = self._select_training_loop(x) return func.fit( self, x=x, y=y, batch_size=batch_size, epochs=epochs, verbose=verbose, callbacks=callbacks, validation_split=validation_split, validation_data=validation_data, shuffle=shuffle, class_weight=class_weight, sample_weight=sample_weight, initial_epoch=initial_epoch, steps_per_epoch=steps_per_epoch, validation_steps=validation_steps, validation_freq=validation_freq, max_queue_size=max_queue_size, workers=workers, use_multiprocessing=use_multiprocessing)对于大的逻辑块,可以在最开始相同的缩进处以#开始写注释。
至于行注释,可以在一行后面跟着两个空格,然后以#开头加入注释。
# This is an example to demonstrate how to comment. # Please note this function must be used carefully. def solve(x): if x == 1: # This is only one exception. return False return True变量命名拒绝使用a b c d 这样毫无意义的单字符,应该使用能够代表其意思的变量名。
一般来说,变量使用小写,通过下划线串联起来,例:data_format。
如果是类的私有变量,前面需要增加两个下划线。
对于常量,最好的做法是全部用大写,并通过下划线连接,例:WAIT_TIME
对于函数名,同样使用小写的方式,通过下划线连接起来。例:launch_nuclear_missile()
对于类名,则应该首字母大写,然后合并起来,例:class SpatialDropout2D()
编程中核心思想是,不写重复代码。重复代码大概率可以通过使用条件、循环、构造函数和类来解决。
示例
if i_am_rich: money = 100 send(money) else: money = 10 send(money)send语句出现了两次,所以完全可以合并一下
if i_am_rich: money = 100 else: money = 10 send(money)示例
def send(money): if is_server_dead: LOG('server dead') return else: if is_server_timed_out: LOG('server timed out') return else: result = get_result_from_server() if result == MONEY_IS_NOT_ENOUGH: LOG('you do not have enough money') return else: if result == TRANSACTION_SUCCEED: LOG('OK') return else: LOG('something wrong') return优化后
def send(money): if is_server_dead: LOG('server dead') return if is_server_timed_out: LOG('server timed out') return result = get_result_from_server() if result == MONET_IS_NOT_ENOUGH: LOG('you do not have enough money') return if result == TRANSACTION_SUCCEED: LOG('OK') return LOG('something wrong')示例
拆分类 class Person: def __init__(self, name, sex, age, job_title, job_description, company_name): self.name = name self.sex = sex self.age = age self.job_title = job_title self.job_description = description self.company_name = company_namejob在其中出现了很多次,而且它们表达的是一个意义实体,这种情况下,可以考虑将这部分分解出来,作为单独的类
class Person: def __init__(self, name, sex, age, job_title, job_description, company_name): self.name = name self.sex = sex self.age = age self.job = Job(job_title, job_description, company_name) class Job: def __init__(self, job_title, job_description, company_name): self.job_title = job_title self.job_description = description self.company_name = company_name