Foreword
There is no rule without rules, and the same is true for code. This article will introduce some of the more commonly used Python code specifications that you follow when doing your own projects.
Naming
Case
- Module name writing:
module_name
- Package name writing:
package_name
- Class name:
ClassName
- Method name:
method_name
- Exception name:
ExceptionName
- Function name:
function_name
- Global constant name:
GLOBAL_CONSTANT_NAME
- Global variable name:
global_var_name
- Instance name:
instance_var_name
- Function parameter name:
function_parameter_name
- Local variable name:
local_var_name
Naming convention
- Function names, variable names and file names should be descriptive and try to avoid abbreviations, except for counters and iterators, as
e
in exception declarations intry/except
and asf
of the file handle in the >with - Starting with a single underscore (_) indicates that the variable or function is protected and should not be accessed from outside (except by subclasses).
Comments
Functions and methods
A function must have a docstring unless it meets the following conditions:
- Not visible from the outside
- very short
- easy to understand
The docstring should contain a detailed description of what the function does, as well as its inputs and outputs. Normally, one shouldn’t describe “how” unless it’s some complex algorithm. The docstring should provide enough information that when someone else writes code to call the function, they don’t need to look at a line of code, just the docstring.
There are many styles of docstrings, such as Google style and Numpy style. The Numpy style docstring is more recommended here. The basic writing method is as follows:
def download_song(song_info: SongInfo, save_dir: str, quality=SongQuality.STANDARD) -> str: """ download online music to local Parameters ---------- song_info: SongInfo song information save_dir: str directory to save the downloaded audio file quality: SongQuality song sound quality Returns ------- song_path: str save path of audio file, empty string when the download fails Raises ------ AudioQualityError: thrown when the sound quality is illegal """ pass
Block comments and line comments
The most important areas to write comments are the technical parts of the code. For complex operations, several lines of comments should be written before the operation begins. Code that is not self-explanatory should have comments added at the end of its lines. To improve readability, comments should leave the code at least 2 spaces.
# We use a weighted dictionary search to find out where i is in # the array. We extrapolate position based on the largest num # in the array and the array size and then do binary search to # get the exact number. if i & amp; (i-1) == 0: # True if i is 0 or a power of 2.
On the other hand, never describe the code, the person reading the code may know Python better than you do, they just don’t know what your code is doing.
# BAD COMMENT: increase i i+=1
Indent
Use 4 spaces to indent code, never use tabs, and don’t mix tabs and spaces. In the case of line concatenation, the wrapped element should be vertically aligned, or a hanging indent of 4 spaces should be used (in which case there should be no parameters on the first line).
that’s amazing:
# Vertical alignment parameters foo = long_function_name(var_one, var_two, var_three, var_four) # Vertical alignment within dictionary foo = { "long_dictionary_key": value1 + value2, ... } # 4 spaces hanging indent, no parameters after the left bracket foo = long_function_name( var_one, var_two, var_three, var_four ) # 4 spaces hanging indent within dictionary foo = { "long_dictionary_key": long_dictionary_value, ... }
You don’t want that kind of thing:
# Parameters cannot be carried after the left bracket foo = long_function_name(var_one, var_two, var_three, var_four ) # Disable hanging indentation of 2 spaces foo = long_function_name( var_one, var_two, var_three, var_four ) # Hanging indentation is required within the dictionary foo = { "long_dictionary_key": long_dictionary_value, ... }
When writing code, do not indent too many levels, generally no more than 4 levels, otherwise it will cause difficulty in reading. Indentation in Python generally comes from statement blocks such as if-else
, for
and while
. One way to reduce indentation is to write if
does not write else
, for example:
def update_by_ids(self, entities: List[Entity]) -> bool: """ update multi records Parameters ---------- entities: List[Entity] entity instances Returns ------- success: bool whether the update is successful """ # If the conditions are not met, return to the default value directly if not entities: return True # Assume this is a bunch of complex business code db = self.get_database() db.transaction() #Create sql statement id_ = self.fields[0] values = ','.join([f'{i} = :{i}' for i in self.fields[1:]]) sql = f"UPDATE {self.table} SET {values} WHERE {id_} = :{id_}" self.query.prepare(sql) return db.commit()
You can also use continue
to reduce unnecessary indentation in for
and while
:
bbboxes = [] for contour in contours: if cv.contourArea(contour) < 500: continue x, y, bw, bh = cv.boundingRect(contour) bboxes.append([x, y, bw, bh])
Line break
Two empty lines between top-level definitions, such as function or class definitions. There should be a blank line between method definitions, class definitions and the first method. In functions or methods, if you think it is appropriate, leave a blank line in some places, such as after if-else
, for
and while
One line, and add blank lines between different logic:
def download_cover(url: str, singer: str, album: str) -> str: """ download online album cover Parameters ---------- url:str the url of online album cover singer:str singer name album:str album name Returns ------- save_path: str save path of album cover, empty string when the download fails """ if not url.startswith('http'): return '' # request data headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) ' 'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36' } response = requests.get(url, headers=headers) response.raise_for_status() pic_data = response.content # save album cover return Cover(singer, album).save(pic_data)
Guide package
Imports should always be placed at the top of the file, after module comments and docstrings, and before module global variables and constants. The import should be in the order of standard library -> third-party packages -> project code:
# coding:utf-8 import base64 import json from pathlib import Path from typing import Union import requests from common.database.entity import SongInfo from common.url import FakeUrl from .crawler_base import CrawlerBase, MvQuality
Function length
There is no hard limit on function length. But if a function exceeds 40 lines, you should consider whether it can be broken down without damaging the structure of the program. Because even if a long function works well, someone may modify it and add some new behavior a few months later, which can easily lead to hard-to-find bugs. Keep functions concise to make them easier to read and modify. When encountering some very long functions, if you find it difficult to debug or want to use part of the function elsewhere, you may wish to consider splitting the long function.
Type annotations
-
Public APIs require annotations
-
Annotate code that is prone to type-related errors. For example, the
image
of the following code may be anumpy
array, or it may be ofImage
type. Which type needs to be specified:def draw_bboxes(image: np.ndarray, bboxes: Union[np.ndarray, list], labels: List[str]) -> Image: pass
-
You can use the end-of-line comment
# type:
:persons = [] # type: List[Person]
Parameter and return value types
When a function needs to pass in or return multiple values, you can consider encapsulating these related values into a class as data members. As shown in the following code, you can easily create an entity class using the dataclass
decorator provided by python3.7, and then you can pass in and out instances of the entity class:
from dataclasses import dataclass @dataclass classSongInfo: """ Song information """ file: str = None title: str = None singer: str = None album: str = None year: int = None genre: str = None duration: int = None track: int = None track_total: int = None disc: int = None disc_total: int = None create_time: int = None modified_time: int = None class SongInfoReader(SongInfoReaderBase): """ Song information reader """ def read(self, file: Union[str, Path]): if not isinstance(file, Path): file = Path(file) tag = TinyTag.get(file) file_ = str(file).replace('\', '/') title = tag.title or file.stem singer = tag.artist or self.singer album = tag.album or self.album year = self.__get_year(tag, file) genre = tag.genre or self.genre duration = int(tag.duration) track = self._parseTrack(tag.track or self.track) track_total = int(tag.track_total or self.track_total) disc = int(tag.disc or self.disc) disc_total = int(tag.disc_total or self.disc_total) create_time = int(file.stat().st_ctime) modified_time = int(file.stat().st_mtime) return SongInfo( file=file_, title=title, singer=singer, album=album, year=year, genre=genre, duration=duration, track=track, track_total=track_total, disc=disc, disc_total=disc_total, createTime=create_time, modifiedTime=modified_time ) class KuWoMusicCrawler: """ Kuwo music crawler """ def get_song_url(self, song_info: SongInfo) -> str: if not FakeUrl.isFake(song_info.file): return song_info.file # send request for play url rid = KuWoFakeSongUrl.getId(song_info.file) url = f'http://www.kuwo.cn/api/v1/www/music/playUrl?mid={rid} & amp;type=convert_url3 & amp;br=128kmp3' response = requests.get(url, headers=self.headers) response.raise_for_status() play_url = json.loads(response.text)['data']['url'] return play_url
Never put these fields in a dictionary or list for temporary convenience, and then use them as parameters or return values of functions. The dictionary is momentarily cool and reconstructs the crematorium.
Write at the end
If the above specifications can be followed, I believe the code will not emit bad smells so easily. For more coding standards, you can see the Google Open Source Project Style Guide, and this article also refers to part of the guide. If you want to write more elegant code, you can read books and blogs related to design patterns. Here we recommend “Mastering Python Design Patterns” and the tutorial Refactoring GURU. We also highly recommend the following YouTube video tutorials:
- 7 Python Code Smells: Olfactory Offenses To Avoid At All Costs
- More Python Code Smells: Avoid These 7 Smelly Snags
- Uncle Bob’s SOLID principles made easy – in Python!
The rapid rise of Python is extremely beneficial to the entire industry, but “There are many popular people and not many people
“, which has led to a lot of criticism, but it still cannot stop its popularity. development momentum.
If you are interested in Python and want to learn Python, here I would like to share with you a Complete set of Python learning materials, which I compiled during my own study. I hope it can help you, let’s work together!
Friends in need can click the link below to get it for free or Scan the QR code below to get it for free
Python complete set of learning materials
1Getting started with zero basics
① Learning route
For students who have never been exposed to Python, we have prepared a detailed Learning and Growth Roadmap for you. It can be said to be the most scientific and systematic learning route. You can follow the above knowledge points to find corresponding learning resources to ensure that you learn more comprehensively.
② Route corresponding learning video
There are also many learning videos suitable for beginners. With these videos, you can easily get started with Python~
③Exercise questions
After each video lesson, there are corresponding exercises to test your learning results haha!
2Domestic and foreign Python books and documents
① Documents and books
3Python toolkit + project source code collection
①Python toolkit
The commonly used development software for learning Python is here! Each one has a detailed installation tutorial to ensure you can install it successfully!
②Python practical case
Optical theory is useless. You must learn to type code along with it and practice it in order to apply what you have learned to practice. At this time, you can learn from some practical cases. 100+ practical case source codes are waiting for you!
③Python mini game source code
If you feel that the practical cases above are a bit boring, you can try writing your own mini-game in Python to add a little fun to your learning process!
4Python interview questions
After we learn Python, we can go out and find a job if we have the skills! The following interview questions are all from first-tier Internet companies such as Alibaba, Tencent, Byte, etc., and Alibaba bosses have given authoritative answers. I believe everyone can find a satisfactory job after reviewing this set of interview materials.
5Python part-time channel
Moreover, after learning Python, you can also take orders and make money on major part-time platforms. I have compiled various part-time channels + part-time precautions + how to communicate with customers into documents.
All the above information , if friends need it, you can scan the QR code below to get it for free