mirror of
https://github.com/google/styleguide.git
synced 2024-03-22 13:11:43 +08:00
Project import generated by Copybara.
PiperOrigin-RevId: 584359357
This commit is contained in:
parent
6ebcd8cee2
commit
4d9a47834b
251
pyguide.md
251
pyguide.md
|
@ -47,6 +47,7 @@ See README.md for details.
|
||||||
+ [3.8.2 Modules](#s3.8.2-comments-in-modules)
|
+ [3.8.2 Modules](#s3.8.2-comments-in-modules)
|
||||||
+ [3.8.2.1 Test modules](#s3.8.2.1-test-modules)
|
+ [3.8.2.1 Test modules](#s3.8.2.1-test-modules)
|
||||||
+ [3.8.3 Functions and Methods](#s3.8.3-functions-and-methods)
|
+ [3.8.3 Functions and Methods](#s3.8.3-functions-and-methods)
|
||||||
|
+ [3.8.3.1 Overridden Methods](#s3.8.3.1-overridden-methods)
|
||||||
+ [3.8.4 Classes](#s3.8.4-comments-in-classes)
|
+ [3.8.4 Classes](#s3.8.4-comments-in-classes)
|
||||||
+ [3.8.5 Block and Inline Comments](#s3.8.5-block-and-inline-comments)
|
+ [3.8.5 Block and Inline Comments](#s3.8.5-block-and-inline-comments)
|
||||||
+ [3.8.6 Punctuation, Spelling, and Grammar](#s3.8.6-punctuation-spelling-and-grammar)
|
+ [3.8.6 Punctuation, Spelling, and Grammar](#s3.8.6-punctuation-spelling-and-grammar)
|
||||||
|
@ -213,8 +214,8 @@ that the arguments are actually unused.
|
||||||
<a id="imports"></a>
|
<a id="imports"></a>
|
||||||
### 2.2 Imports
|
### 2.2 Imports
|
||||||
|
|
||||||
Use `import` statements for packages and modules only, not for individual
|
Use `import` statements for packages and modules only, not for individual types,
|
||||||
classes or functions.
|
classes, or functions.
|
||||||
|
|
||||||
<a id="s2.2.1-definition"></a>
|
<a id="s2.2.1-definition"></a>
|
||||||
<a id="221-definition"></a>
|
<a id="221-definition"></a>
|
||||||
|
@ -406,10 +407,11 @@ Exceptions must follow certain conditions:
|
||||||
raise a `ValueError` to indicate a programming mistake like a violated
|
raise a `ValueError` to indicate a programming mistake like a violated
|
||||||
precondition (such as if you were passed a negative number but required a
|
precondition (such as if you were passed a negative number but required a
|
||||||
positive one). Do not use `assert` statements for validating argument values
|
positive one). Do not use `assert` statements for validating argument values
|
||||||
of a public API. `assert` is used to ensure internal correctness, not to
|
of a public API. `assert` is used to ensure internal correctness or
|
||||||
enforce correct usage nor to indicate that some unexpected event occurred.
|
to verify expectations in
|
||||||
If an exception is desired in the latter cases, use a raise statement. For
|
[pytest](https://pytest.org) based tests, not to enforce correct usage nor
|
||||||
example:
|
to indicate that some unexpected event occurred. If an exception is desired
|
||||||
|
in the latter cases, use a raise statement. For example:
|
||||||
|
|
||||||
|
|
||||||
```python
|
```python
|
||||||
|
@ -642,20 +644,18 @@ Complicated comprehensions or generator expressions can be hard to read.
|
||||||
<a id="comprehensions-decision"></a>
|
<a id="comprehensions-decision"></a>
|
||||||
#### 2.7.4 Decision
|
#### 2.7.4 Decision
|
||||||
|
|
||||||
Okay to use for simple cases. Each portion must fit on one line: mapping
|
Comprehensions are allowed, however multiple `for` clauses or filter expressions
|
||||||
expression, `for` clause, filter expression. Multiple `for` clauses or filter
|
are not permitted. Optimize for readability, not conciseness.
|
||||||
expressions are not permitted. Use loops instead when things get more
|
|
||||||
complicated.
|
|
||||||
|
|
||||||
```python
|
```python
|
||||||
Yes:
|
Yes:
|
||||||
result = [mapping_expr for value in iterable if filter_expr]
|
result = [mapping_expr for value in iterable if filter_expr]
|
||||||
|
|
||||||
result = [{'key': value} for value in iterable
|
result = [
|
||||||
if a_long_filter_expression(value)]
|
is_valid(metric={'key': value})
|
||||||
|
for value in interesting_iterable
|
||||||
result = [complicated_transform(x)
|
if a_longer_filter_expression(value)
|
||||||
for x in iterable if predicate(x)]
|
]
|
||||||
|
|
||||||
descriptive_name = [
|
descriptive_name = [
|
||||||
transform({'key': key, 'value': value}, color='black')
|
transform({'key': key, 'value': value}, color='black')
|
||||||
|
@ -669,32 +669,29 @@ Yes:
|
||||||
if x * y > 10:
|
if x * y > 10:
|
||||||
result.append((x, y))
|
result.append((x, y))
|
||||||
|
|
||||||
return {x: complicated_transform(x)
|
return {
|
||||||
|
x: complicated_transform(x)
|
||||||
for x in long_generator_function(parameter)
|
for x in long_generator_function(parameter)
|
||||||
if x is not None}
|
if x is not None
|
||||||
|
}
|
||||||
|
|
||||||
squares_generator = (x**2 for x in range(10))
|
return (x**2 for x in range(10))
|
||||||
|
|
||||||
unique_names = {user.name for user in users if user is not None}
|
unique_names = {user.name for user in users if user is not None}
|
||||||
|
|
||||||
eat(jelly_bean for jelly_bean in jelly_beans
|
|
||||||
if jelly_bean.color == 'black')
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
No:
|
No:
|
||||||
result = [complicated_transform(
|
|
||||||
x, some_argument=x+1)
|
|
||||||
for x in iterable if predicate(x)]
|
|
||||||
|
|
||||||
result = [(x, y) for x in range(10) for y in range(5) if x * y > 10]
|
result = [(x, y) for x in range(10) for y in range(5) if x * y > 10]
|
||||||
|
|
||||||
return ((x, y, z)
|
return (
|
||||||
|
(x, y, z)
|
||||||
for x in range(5)
|
for x in range(5)
|
||||||
for y in range(5)
|
for y in range(5)
|
||||||
if x != y
|
if x != y
|
||||||
for z in range(5)
|
for z in range(5)
|
||||||
if y != z)
|
if y != z
|
||||||
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
<a id="s2.8-default-iterators-and-operators"></a>
|
<a id="s2.8-default-iterators-and-operators"></a>
|
||||||
|
@ -848,8 +845,8 @@ function may only contain an expression.
|
||||||
<a id="lambdas-decision"></a>
|
<a id="lambdas-decision"></a>
|
||||||
#### 2.10.4 Decision
|
#### 2.10.4 Decision
|
||||||
|
|
||||||
Okay to use them for one-liners. If the code inside the lambda function is
|
Lambdas are allowed. If the code inside the lambda function spans multiple lines
|
||||||
longer than 60-80 chars, it's probably better to define it as a regular
|
or is longer than 60-80 chars, it might be better to define it as a regular
|
||||||
[nested function](#lexical-scoping).
|
[nested function](#lexical-scoping).
|
||||||
|
|
||||||
For common operations like multiplication, use the functions from the `operator`
|
For common operations like multiplication, use the functions from the `operator`
|
||||||
|
@ -992,7 +989,7 @@ _FOO = flags.DEFINE_string(...)
|
||||||
|
|
||||||
No: def foo(a, b=[]):
|
No: def foo(a, b=[]):
|
||||||
...
|
...
|
||||||
No: def foo(a, b=time.time()): # The time the module was loaded???
|
No: def foo(a, b=time.time()): # Is `b` supposed to represent when this module was loaded?
|
||||||
...
|
...
|
||||||
No: def foo(a, b=_FOO.value): # sys.argv has not yet been parsed...
|
No: def foo(a, b=_FOO.value): # sys.argv has not yet been parsed...
|
||||||
...
|
...
|
||||||
|
@ -1798,6 +1795,150 @@ Trailing commas in sequences of items are recommended only when the closing
|
||||||
container token `]`, `)`, or `}` does not appear on the same line as the final
|
container token `]`, `)`, or `}` does not appear on the same line as the final
|
||||||
element, as well as for tuples with a single element. The presence of a trailing
|
element, as well as for tuples with a single element. The presence of a trailing
|
||||||
comma is also used as a hint to our Python code auto-formatter
|
comma is also used as a hint to our Python code auto-formatter
|
||||||
|
[Black](https://github.com/psf/black) or [Pyink](https://github.com/google/pyink)
|
||||||
|
to direct it to auto-format the container of items to one item per line when the
|
||||||
|
`,` after the final element is present.
|
||||||
|
|
||||||
|
```python
|
||||||
|
Yes: golomb3 = [0, 1, 3]
|
||||||
|
golomb4 = [
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
4,
|
||||||
|
6,
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
No: golomb4 = [
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
4,
|
||||||
|
6,]
|
||||||
|
```
|
||||||
|
|
||||||
|
<a id="s3.5-blank-lines"></a>
|
||||||
|
<a id="35-blank-lines"></a>
|
||||||
|
|
||||||
|
<a id="blank-lines"></a>
|
||||||
|
### 3.5 Blank Lines
|
||||||
|
|
||||||
|
Two blank lines between top-level definitions, be they function or class
|
||||||
|
definitions. One blank line between method definitions and between the docstring
|
||||||
|
of a `class` and the first method. No blank line following a `def` line. Use
|
||||||
|
single blank lines as you judge appropriate within functions or methods.
|
||||||
|
|
||||||
|
Blank lines need not be anchored to the definition. For example, related
|
||||||
|
comments immediately preceding function, class, and method definitions can make
|
||||||
|
sense. Consider if your comment might be more useful as part of the docstring.
|
||||||
|
|
||||||
|
<a id="s3.6-whitespace"></a>
|
||||||
|
<a id="36-whitespace"></a>
|
||||||
|
|
||||||
|
<a id="whitespace"></a>
|
||||||
|
### 3.6 Whitespace
|
||||||
|
|
||||||
|
Follow standard typographic rules for the use of spaces around punctuation.
|
||||||
|
|
||||||
|
No whitespace inside parentheses, brackets or braces.
|
||||||
|
|
||||||
|
```python
|
||||||
|
Yes: spam(ham[1], {'eggs': 2}, [])
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
No: spam( ham[ 1 ], { 'eggs': 2 }, [ ] )
|
||||||
|
```
|
||||||
|
|
||||||
|
No whitespace before a comma, semicolon, or colon. Do use whitespace after a
|
||||||
|
comma, semicolon, or colon, except at the end of the line.
|
||||||
|
|
||||||
|
```python
|
||||||
|
Yes: if x == 4:
|
||||||
|
print(x, y)
|
||||||
|
x, y = y, x
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
No: if x == 4 :
|
||||||
|
print(x , y)
|
||||||
|
x , y = y , x
|
||||||
|
```
|
||||||
|
|
||||||
|
No whitespace before the open paren/bracket that starts an argument list,
|
||||||
|
indexing or slicing.
|
||||||
|
|
||||||
|
```python
|
||||||
|
Yes: spam(1)
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
No: spam (1)
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
Yes: dict['key'] = list[index]
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
No: dict ['key'] = list [index]
|
||||||
|
```
|
||||||
|
|
||||||
|
No trailing whitespace.
|
||||||
|
|
||||||
|
Surround binary operators with a single space on either side for assignment
|
||||||
|
(`=`), comparisons (`==, <, >, !=, <>, <=, >=, in, not in, is, is not`), and
|
||||||
|
Booleans (`and, or, not`). Use your better judgment for the insertion of spaces
|
||||||
|
around arithmetic operators (`+`, `-`, `*`, `/`, `//`, `%`, `**`, `@`).
|
||||||
|
|
||||||
|
```python
|
||||||
|
Yes: x == 1
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
No: x<1
|
||||||
|
```
|
||||||
|
|
||||||
|
Never use spaces around `=` when passing keyword arguments or defining a default
|
||||||
|
parameter value, with one exception:
|
||||||
|
[when a type annotation is present](#typing-default-values), *do* use spaces
|
||||||
|
around the `=` for the default parameter value.
|
||||||
|
|
||||||
|
```python
|
||||||
|
Yes: def complex(real, imag=0.0): return Magic(r=real, i=imag)
|
||||||
|
Yes: def complex(real, imag: float = 0.0): return Magic(r=real, i=imag)
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
No: def complex(real, imag = 0.0): return Magic(r = real, i = imag)
|
||||||
|
No: def complex(real, imag: float=0.0): return Magic(r = real, i = imag)
|
||||||
|
```
|
||||||
|
|
||||||
|
Don't use spaces to vertically align tokens on consecutive lines, since it
|
||||||
|
becomes a maintenance burden (applies to `:`, `#`, `=`, etc.):
|
||||||
|
|
||||||
|
```python
|
||||||
|
Yes:
|
||||||
|
foo = 1000 # comment
|
||||||
|
long_name = 2 # comment that should not be aligned
|
||||||
|
|
||||||
|
dictionary = {
|
||||||
|
'foo': 1,
|
||||||
|
'long_name': 2,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
No:
|
||||||
|
foo = 1000 # comment
|
||||||
|
long_name = 2 # comment that should not be aligned
|
||||||
|
|
||||||
|
dictionary = {
|
||||||
|
'foo' : 1,
|
||||||
|
'long_name': 2,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
<a id="Python_Interpreter"></a>
|
<a id="Python_Interpreter"></a>
|
||||||
<a id="s3.7-shebang-line"></a>
|
<a id="s3.7-shebang-line"></a>
|
||||||
|
@ -1929,15 +2070,6 @@ should use the same style as the docstring for an attribute or a
|
||||||
<a href="#doc-function-args">function argument</a> (`"""The Bigtable path."""`,
|
<a href="#doc-function-args">function argument</a> (`"""The Bigtable path."""`,
|
||||||
rather than `"""Returns the Bigtable path."""`).
|
rather than `"""Returns the Bigtable path."""`).
|
||||||
|
|
||||||
A method that overrides a method from a base class may have a simple docstring
|
|
||||||
sending the reader to its overridden method's docstring, such as `"""See base
|
|
||||||
class."""`. The rationale is that there is no need to repeat in many places
|
|
||||||
documentation that is already present in the base method's docstring. However,
|
|
||||||
if the overriding method's behavior is substantially different from the
|
|
||||||
overridden method, or details need to be provided (e.g., documenting additional
|
|
||||||
side effects), a docstring with at least those differences is required on the
|
|
||||||
overriding method.
|
|
||||||
|
|
||||||
Certain aspects of a function should be documented in special sections, listed
|
Certain aspects of a function should be documented in special sections, listed
|
||||||
below. Each section begins with a heading line, which ends with a colon. All
|
below. Each section begins with a heading line, which ends with a colon. All
|
||||||
sections other than the heading should maintain a hanging indent of two or four
|
sections other than the heading should maintain a hanging indent of two or four
|
||||||
|
@ -2057,6 +2189,47 @@ def fetch_smalltable_rows(
|
||||||
"""
|
"""
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<a id="s3.8.3.1-overridden-methods"></a>
|
||||||
|
|
||||||
|
<a id="overridden-method-docs"></a>
|
||||||
|
##### 3.8.3.1 Overridden Methods
|
||||||
|
|
||||||
|
A method that overrides a method from a base class does not need a docstring if
|
||||||
|
it is explicitly decorated with
|
||||||
|
[`@override`](https://typing-extensions.readthedocs.io/en/latest/#override)
|
||||||
|
(from `typing_extensions` or `typing` modules), unless the overriding method's
|
||||||
|
behavior materially refines the base method's contract, or details need to be
|
||||||
|
provided (e.g., documenting additional side effects), in which case a docstring
|
||||||
|
with at least those differences is required on the overriding method.
|
||||||
|
|
||||||
|
```python
|
||||||
|
from typing_extensions import override
|
||||||
|
|
||||||
|
class Parent:
|
||||||
|
def do_something(self):
|
||||||
|
"""Parent method, includes docstring."""
|
||||||
|
|
||||||
|
# Child class, method annotated with override.
|
||||||
|
class Child(Parent):
|
||||||
|
@override
|
||||||
|
def do_something(self):
|
||||||
|
pass
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Child class, but without @override decorator, a docstring is required.
|
||||||
|
class Child(Parent):
|
||||||
|
def do_something(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Docstring is trivial, @override is sufficient to indicate that docs can be
|
||||||
|
# found in the base class.
|
||||||
|
class Child(Parent):
|
||||||
|
@override
|
||||||
|
def do_something(self):
|
||||||
|
"""See base class."""
|
||||||
|
```
|
||||||
|
|
||||||
<a id="s3.8.4-comments-in-classes"></a>
|
<a id="s3.8.4-comments-in-classes"></a>
|
||||||
<a id="384-classes"></a>
|
<a id="384-classes"></a>
|
||||||
<a id="comments-in-classes"></a>
|
<a id="comments-in-classes"></a>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user