python - 什么是“好的 Python 代码”,这如何符合准则?
问题描述
当你第一次开始时,我一直听说写好代码和写坏代码。毕竟,如果它运行并完成了 0 个问题的工作,这还不够吗?你能以此为例吗?我用我所知道的和必须学习的东西工作,所以我确信它可以被分开。除了 PEP8 和其他东西,还有什么好的代码?
import random
def cownbull():
"""This one generates a non repeating random number"""
def cownbull2():
"""This one is running the game due to local variable problems; keyboard
almost thrown"""
print(num2guess, 'is the generated number')
print("Let's play a game of Cowbull!") # explanation
print("I will generate a number, and you have to guess the
numbers one digit at a time.")
print("For every number in the wrong place, you get a cow. For
every one in the right place, you get a bull.")
print("The game ends when you get 4 bulls!")
print("There are no repeated digits")
guesses = 0
cow = 0
bull = 0
while True:
print("cows:", cow,'|','bulls:',bull,'|','guesses:',guesses)
cow = 0
bull = 0
user = input('Guess a four digit number: ')
if len(user) >4:
print('type four digits!')
cownbull()
guesses = guesses + 1
for x in user:
for y in str(num2guess):
if x == y:
if user.index(x, 0, 4) ==
str(num2guess).index(y, 0, 4):
bull += 1
if bull == 4:
print('Nice game!')
cownbull()
else:
cow += 1
else:
pass
num2guess = random.randint(1000, 9999)
count = 0
while count < 4:
for i in str(num2guess):
count = count + 1
print(i)
str2guess = str(num2guess)
print(str2guess.count(i))
if str2guess.count(i) != 1:
print('calculating new number....')
cownbull()
else:
cownbull2()
cownbull()
解决方案
2020 年更新:我认为我应该参考下面的 COBOL 评论和 COVID-19 以及为什么好的代码很重要来更新此内容。因为,正如我们现在从非运作的国家和政府系统中清楚地看到的那样,它影响着人们的生活。
毕竟,如果它运行并完成了 0 个问题的工作,这还不够吗?
不,甚至没有接近。这让我和几乎所有其他软件开发人员都很恼火。让我们看一个经常发生的场景。
你制作了一个程序,它“正常工作”。但是,你的代码很糟糕。然后其他人必须努力。你猜怎么着?我可以挖掘一堆复制粘贴的垃圾,unpythonic 代码,重做所有这些,假设我什至可以解开有人设法将 0 条评论和逻辑思路放在一起的科学怪人逻辑。这不是针对您的代码 - 而是它在“狂野”中发生的程度。
这是难以管理的,尤其是当它需要添加时,如果你在 6 个月后用你刚刚编码的东西打开你的编辑器,你会知道它是做什么的吗?然后以这种方式编码的人期望其他开发人员能够使用他们的“功能”代码。还不够好。
有些代码库人们多年不接触 - 然后成为遗留代码库 - 这是怪物(看着你的 COBOL),只有少数人知道任何事情,下一个开发人员或团队几乎不可能管理到合理的程度。
这是一个非常简单的案例.. 你这里可能有 100 行。当它有数十万并以这种方式阅读时会发生什么?当您拥有一个由开发人员组成的整个团队时会发生什么,每个开发人员都在推送代码、不同的分支、合并等。软件开发很复杂,并且存在实践来最大限度地减少错误、开发人员之间的流畅性以及限制复杂性/不良代码。
干净的代码是一种很少有人掌握的艺术形式。
干净的代码- 如果成本是一个问题,您可能会在其他地方或您的图书馆(或取决于语言环境的等效物)中找到它。我强烈建议阅读某种形式的关于干净编码的书。这将是大开眼界。
除了 PEP8 和其他东西,还有什么好的代码?
一句话,我应该能够打开我的编辑器,看看你的代码,把它读成一堆简单的逻辑——多亏了 Python,几乎和英文句子一样——自上而下,没有停顿,然后说“是的,这就是我所期望的”
你会让人争论某些设计模式,例如测试驱动开发或行为驱动,并且这些模式有很多优点和用例。但是,这纯粹关注代码读取方式的语义。编写代码本身的技巧。
我会立即重构您自己代码中的内容并考虑“代码异味”
- 点评:“”“由于局部变量问题,这个正在运行游戏;键盘差点摔倒”“”。
虽然这样的评论很可爱,但它们并没有帮助。您只需要在需要为进入代码库的人和您自己提供有问题的部分时才需要简短的注释。
像这样的嵌套函数:有时会使用闭包。这不是其中的一个。
冗余定义和逻辑:在需要的时候使用它,只在需要的时候使用。
代码的一般重组和压缩。你是新的,所以你现在还没有这些,但它们会随着时间的推移而出现。所以我不会过多地吹毛求疵。
文档字符串:在实际代码库中,文档字符串用于记录函数,顾名思义。参数、返回值、期望等。库甚至可以从中生成完整的文档页面,例如sphinx
向后兼容性:这适用于需要遗留支持的大型代码库。如果您访问几乎任何公共存储库,您会发现一个
compat.py
在版本之间架起导入的桥梁。
面向对象语言:
一般来说,我们可以说一些关于面向对象语言中的干净代码的事情。
顾名思义,面向对象的语言以“对象”的定义为中心。在 python 中,这些将是你的类。
在 python 2 中(也适用于 Python 3,只是“旧式”):
class ClassName(object):
....
在python 3中:
class ClassName:
....
多态性和继承
在这里,您的类用于封装对象及其方法/属性。此外,面向对象的语言本质上提供了多态性。
多态性允许您提供以多种形式起作用的接口。这个名字本身就从希腊词根“poly”(意思是许多)和“morphism”(意思是形式)中暗示了这一点。
假设我建立了一个类来描述动物及其属性。我可以为every.single.type.of.animal 建立一个新类。或者,提供常用的方法和属性,并在必要时覆盖它们。这是动物王国的一个实际例子
多态是在适当的时候编写干净代码的绝妙方法。同样,对于继承。
建筑模块
面向对象语言的强大功能之一就是能够将事物分解为“构建块”,可以说并将它们混合在一起以提供混合功能。
但是,当您编写大量这些将它们捆绑在一起以获得更高功能的对象然后需要进行更改或想在其他地方使用它时会发生什么?
您是否必须通过或带走整个面向对象的动物园?在我看来,这不是很干净,并且让开发人员感到沮丧。谨慎使用这种编程方法。
就个人而言,我喜欢它,因为我非常喜欢 Django Web 框架,喜欢使用 mixins 和一些技巧的灵活性。所以,我个人倾向于这种类型的编程。
在 Python 中编写干净代码的总结:
做到以上几点,擅长多态和继承,遵循禅宗,知道如何分解事物并保持事物简洁而不影响可读性,并正确记录您的代码。这是 90% 的干净代码。剩下的就是磨练工艺。
推荐阅读
- linux - 如何从 oom 终止进程中获取 ppid?
- java - 如何将 Spring Web 应用程序配置为每个端点使用不同的身份验证方法
- python - 使用内部支持的优化器优化 scikit-learn 中 GPR 的 RBF 内核的内核参数
- javascript - 函数属性不是 Polymer 中的函数
- git - 来自特定分支的 TFS 条件拉取请求
- python - 如何将字符串值与文本文件Python中的每一行连接起来
- jenkins - sed 命令的 Jenkins 管道失败
- serverless - 如何在超过 300 秒限制的情况下运行 Aurora-MySQL 耗时的无服务器存储过程
- bind - Spring-ws:无法将前缀绑定到空的命名空间名称
- c - 在 c 中读取 uart,仅通过声明 char 数组来产生垃圾