brief introduction : Why emphasize Writing norms ? It's not really about “ The beauty and ugliness ”, It's about Higher efficiency ( Code reading 、 Development 、 maintain ) With more convenient cooperation ( A global standard ) . Now , No matter what direction the students should carry out “ Write code ” This work , It is a pity , Many friends don't realize : cost 1 Hours to understand code writing standards , You can save yourself 100+ Hours of code time . The charm of code specifications is Really simplify the problem , We don't need to be standard or controversial . In this paper, we mainly use python For example , With pep8 For the main reference material , There are three levels of discussion .
There are three levels in this paper :
- Don't pay attention to these , You're not writing code at all
- These specifications , The essence is to respect the logic of the procedure
- Some of the norms I'm going to ignore , More thinking
Don't pay attention to these , You're not writing code at all
1/2 Take a look at my code two years ago
import tkinter
import tkinter.messagebox
def message_box(error_content):
top = tkinter.Tk() # *********
top.withdraw() # **** Hide the main window
top.update() # ********* need update once
txt=tkinter.messagebox.showinfo(" Tips ",error_content)
top.destroy()
return txt
The above is in use python
Of tkinter
Make a desktop app , It seems that there is no problem ? Big problem , For example, project logic / Design architecture It's really hard to see through these lines of code ; however , The writing habits of the above lines of code , It reflects that one's thinking is not mature enough :
- Notes don't need
# ****
Write it like this , No need at all need update once
This is bullshit , The front is notupdate()
Function? ?(" Tips ",error_content)
There should be a space in the middletxt=tkinter
There should be spaces on the left and right sides
If I were to write , I will implement the following :
import tkinter
from tkinter import messagebox as msg
def show_message_box(error_content):
"""
Piper Egg nests :
Input error message ,messagebox display information
( A skin : Welcome to your attention Piper Egg nests ~)
"""
tk = tkinter.Tk()
tk.withdraw()
tk.update()
txt = msg.showinfo(" Tips ", error_content)
tk.destroy()
return txt
Above :
- I've got rid of some minor problems , For example, whether there are spaces, etc , But that's not the point
- I took the function name from
message_box
Change it toshow_message_box
, becausemessage_box
It looks like a noun , It's not a verb ( To carry out a task ), After the complexity of the project structure , We may have many functions 、 class 、 example , If Don't make a gerund distinction , We can all confuse ourselves with , Also turn back to the source code to check , Waste a lot of time - I annotate ( What does this function do ) On the
""" notes """
in , This interpreter and InelliSense When we call , Make automatic instructions , Here's the picture
2/2 The most basic : Indent 、 Naming and space
friend , If you write code with Indent 、 Naming and space
None of these things will be noticed , The congratulations , This article is likely to take you up a level .
I've just learned c Our freshman , In the computer room VC 6 Knock down the characters one by one :
#include <stdio.h>
int main()
{int a=5,b=7,c;
printf("a=%d,b=%d,c=%d",a,b,c);
return 0;}
Obviously , This kid's code is really just “ Typing characters into the computer ” nothing more ,ta I don't have the logic of the program 、 level . This code is dead , It's not living . I just add a few spaces and carriage returns , To explain , Why are these indentations 、 Naming and space make code real code .
#include <stdio.h>
int main()
{
int a = 5, b = 7, c;
printf("a = %d, b = %d, c = %d", a, b, c);
return 0;
}
Above :
- I put
{}
Independent , And indent the code block , Indicates that the code is a functionmain()
Internal logic - I added spaces , If you put
a=5
Turned intoa = 5
, It's because programmers are people , You also need to read something clearly - I am here
#include <stdio.h>
Andint main()
There is a blank line in between , Because they are two things : The former is responsible for introducing io Standard library , The latter is responsible for executing logic . When writing code , Don't be stingy , To distinguish between different logic and tasks
Is the above discussion too basic ? Now let's python And its official documents pep 8 For example , Let's see more about the logic of the program 、 Official suggestions for code readability .
If someone shows you again next time ta Written “ Dead code ”, You throw this article to ta, Give Way ta Improve !
These specifications , The essence is to respect the logic of the procedure
1/4 Indents and spaces : Embody logic
Indentation Indent
A famous American play 《 Silicon valley 》 There's a plot in it , Programmers can make a lot of noise about using tabs or spaces , It seems to be a matter of principle ?
It's just a joke, of course .
stay python in , Recommended 4 Space to indent . I'm playing kdd cup Yes, I have 2 Space for indented ( official start toolkit in ). I think it doesn't matter , The key is , You have to unify it in the project .
Besides , Indentation is used to represent the structure of a program , If your structure is not inclusive , It's just line breaks , Then use it 4 A space indent would be stupid . as follows .
# recommend
foo = long_function_name(var_one, var_two,
var_three, var_four)
# perhaps
foo = long_function_name(var_one, var_two,
var_three, var_four)
# perhaps
foo = long_function_name(var_one, var_two,
var_three, var_four)
# perhaps
def long_function_name(
var_one, var_two, var_three,
var_four):
print(var_one)
# stupid
foo = long_function_name(var_one, var_two,
var_three, var_four)
# stupid
def long_function_name(
var_one, var_two, var_three,
var_four):
print(var_one)
Why? ? We use the bottom def long_function_name
For example , Have you noticed :
print(var_one)
Should bedef long_function_name
The internal structure of , So it has to be better thandef long_function_name
One more indent before- however
var_one, var_two, var_three
These parameters aredef long_function_name
Part of , Anddef long_function_name
At the same level - The function parameters are aligned with the internal structure of the function , It's easy to confuse
therefore , You only need to Manufacturing differentiation Can . As for you, add two more spaces , Or two less , It doesn't matter ( Unless your organization has specific rules ), Let you and others see the logical structure at a glance .
Should a line break before or after a binary operator?
Besides , pep 8 And recommended operator The location of , I didn't really notice this before .
# No: operators sit far away from their operands
income = (gross_wages +
taxable_interest +
(dividends - qualified_dividends) -
ira_deduction -
student_loan_interest)
# Yes: easy to match operators with operands
income = (gross_wages
+ taxable_interest
+ (dividends - qualified_dividends)
- ira_deduction
- student_loan_interest)
Besides , To prevent compilation errors , I'll add \\
To escape a newline key .
income = (gross_wages \
+ taxable_interest \
+ (dividends - qualified_dividends) \
- ira_deduction \
- student_loan_interest)
Now it seems , It may not be necessary in this case .
Reject meaningless spaces
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
Above is Pet Peeves Suggestions in , Obviously , Too loose structure , It's not good for us to read and see logic . It's a habit common to all programming languages , It's worth cultivating .
Missing values of function variables
# Yes
def complex(real, imag=0.0):
return magic(r=real, i=imag)
# No
def complex(real, imag = 0.0):
return magic(r = real, i = imag)
Above , When defining a missing value , We encourage the removal of =
The space around .
# Yes
def munge(sep: AnyStr = None): ...
def munge(input: AnyStr, sep: AnyStr = None, limit=1000): ...
# No
def munge(input: AnyStr=None): ...
def munge(input: AnyStr, limit = 1000): ...
however , Above , It is worth noting that , If you define the data type of the function ( Such as AnyStr
), Then we need to remind developers to distinguish , Do not remove =
The space around .
2/4 import
Yes: import os
import sys
No: import sys, os
# Yes
i = i + 1
submitted += 1
x = x*2 - 1
hypot2 = x*x + y*y
c = (a+b) * (a-b)
# No
i=i+1
submitted +=1
x = x * 2 - 1
hypot2 = x * x + y * y
c = (a + b) * (a - b)
About import There are several specifications for , I would like to emphasize here that a novice might have “ bad habit ”: Put irrelevant libraries in a import Next .
What's the picture ? It doesn't make any sense . For example, above ,sys
In fact, with os
There is no inclusive relationship , Why should we be stingy in this business import
Well ? And put them together , It's not good for formatter
Help us organize our writing .
3/4 Variable 、 The name of the function
Choose a good naming rule
Different enterprises / organization , Especially large enterprises , There's going to be a naming convention of its own . about java , I think the most commonly used one should be “ hump ” It's named after :
public void printUserName(int index) {
...
}
stay python , Encourage various generic forms of naming , Such as :
printUserName
print_user_name
I think you're in python The most common one is Underline + A lowercase letter In the form of .
stay pep 8 Of Descriptive: Naming Styles There's a label , It's funny :
Capitalized_Words_With_Underscores (ugly!)
Why do you say Capitalized_Words_With_Underscores
“ ugly ” Well ?
I think it is Information redundancy 了 : Underline or capital initial , They are used to space words , Both use , It's really not concise 、 Not elegant .
“ private ” Variable
stay C++ perhaps java in , We are all exposed to private
This kind of concept . Beginners may be confused : Why do variables have to be private 、 Public 、 The protected ?
python Let the beginner avoid this part may produce the incomprehensibility , But it doesn't remove the functions such as private variables , I think it's just pythonic The embodiment of . and , Today's language has this trend , such as go
, Limit initial case sensitive variables private common , Simple and elegant , It also unifies the norms of community development .
about python , We put two underscores before the variables , Then it becomes private . Private variables for the specification and security of the project , Cannot be called externally , I wrote a program as follows .
Above , Call directly Foo.__a
perhaps foo.__b
Will produce AttributeError error . however python To give a “ back door ”, You can still pass _ Class name __ Variable name
Call private variables .
4/4 Respect “ The human mind ”
# Yes
if foo is not None:
# No
if not foo is None:
Above , Maybe the novice will feel not ... is
This structural logic is reversed , It's fun , Although its function is similar to is not
Exactly the same .
Or that sentence , Programmers are people , Everyone likes simple and clear logic . Unless it's a clever trick , otherwise , There's no need to play word games , Reduce efficiency .
# Yes
try:
value = collection[key]
except KeyError:
return key_not_found(key)
else:
return handle_value(value)
# No
try:
# Too broad!
return handle_value(collection[key])
except KeyError:
# Will also catch KeyError raised by handle_value()
return key_not_found(key)
Above , In the use of try catch when , We want to capture KeyError , Then don't be in try Do other operations in . Why? ?
- If
handle_value()
There's something wrong with it , So it's hard for us to passhandle_value(collection[key])
Catch their own mistakes , Because of its relationship withcollection[key]
Possible mistakes are mixed up
# Yes
def foo(x):
if x >= 0:
return math.sqrt(x)
else:
return None
def bar(x):
if x < 0:
return None
return math.sqrt(x)
# No
def foo(x):
if x >= 0:
return math.sqrt(x)
def bar(x):
if x < 0:
return
return math.sqrt(x)
Above , x
Less than 0 when , Can't square , Naturally, you can't input math.sqrt()
. Here we should make the program clearer , Although we know that if a function does nothing, it returns None
, But don't forget to write return None
. use pep 8 Saying , We should be be consistent in return statements.
Some of the norms I'm going to ignore , More thinking
1/3 Maximum number of characters per line ?I say NO.
We know , pep 8 I hope every line of us most 79 Characters .
I think for developers like me , It's really not necessary . and , I've read a lot of good open source frameworks , It doesn't respect that standard either .
The reason is simple , Our production environment is different .
I like big font , And I only have a little laptop , There's no station . Many friends have several screens / Lengthen the screen , And I can only split a small laptop monitor in two . Here's the picture .
Whether it's 79 Characters , still 109 Characters , My editor doesn't even show up in one line , So this code doesn't mean much to me .
Maybe develop python The standard library uses . But not now .
2/3 Note file standards ? I reconsider
pep 8 And pep 257 in , All of them have standardized the way of annotation , as follows .
def complex(real=0.0, imag=0.0):
"""Form a complex number.
Keyword arguments:
real -- the real part (default 0.0)
imag -- the imaginary part (default 0.0)
"""
if imag == 0.0 and real == 0.0:
return complex_zero
...
I'm not very interested in . reason :
- I remember pyCharm in , The default comment doesn't look like this , The specification standard is not the only one
- What standard should be used , I feel like Take the matter on its merits , such as MkDocs Will help us automatically compile comments into documents and publish them online , So we want to use MkDocs when , To learn MkDocs That's good
Above is thu-ml/tianshou Source code , Its annotation uses markdown Written , If you go to the documentation , You'll find that documentation is automatically generated from source code comments .
Amazing. That's what it is. “ Code writing ” The virtue that ought to be : lazy , No repetition , If it can be automated .
3/3 It's better to read more good projects than to read standard documents
Last , Just say no fake tricks .
in my opinion , Read more good code 、 project , Consciously pay attention to the master's writing rules and how to arrange the project structure , It's much more meaningful than reading pep 8 It's much bigger. .