mirror of
https://github.com/google/styleguide.git
synced 2024-03-22 13:11:43 +08:00
Project import generated by Copybara.
PiperOrigin-RevId: 480954960
This commit is contained in:
parent
099770e27c
commit
8638b2665f
124
pyguide.md
124
pyguide.md
|
@ -272,7 +272,7 @@ package twice.
|
||||||
|
|
||||||
Exemptions from this rule:
|
Exemptions from this rule:
|
||||||
|
|
||||||
* Symbols from the following modules and used to support static analysis and
|
* Symbols from the following modules are used to support static analysis and
|
||||||
type checking:
|
type checking:
|
||||||
* [`typing` module](#typing-imports)
|
* [`typing` module](#typing-imports)
|
||||||
* [`collections.abc` module](#typing-imports)
|
* [`collections.abc` module](#typing-imports)
|
||||||
|
@ -524,7 +524,7 @@ global variables must be done through public module-level functions. See
|
||||||
[Naming](#s3.16-naming) below.
|
[Naming](#s3.16-naming) below.
|
||||||
|
|
||||||
While module-level constants are technically variables, they are permitted and
|
While module-level constants are technically variables, they are permitted and
|
||||||
encouraged. For example: `MAX_HOLY_HANDGRENADE_COUNT = 3`. Constants must be
|
encouraged. For example: `_MAX_HOLY_HANDGRENADE_COUNT = 3`. Constants must be
|
||||||
named using all caps with underscores. See [Naming](#s3.16-naming) below.
|
named using all caps with underscores. See [Naming](#s3.16-naming) below.
|
||||||
|
|
||||||
<a id="s2.6-nested"></a>
|
<a id="s2.6-nested"></a>
|
||||||
|
@ -710,8 +710,8 @@ operators is generic. It can be used with any type that supports the operation.
|
||||||
<a id="default-iterators-operators-cons"></a>
|
<a id="default-iterators-operators-cons"></a>
|
||||||
#### 2.8.3 Cons
|
#### 2.8.3 Cons
|
||||||
|
|
||||||
You can't tell the type of objects by reading the method names (e.g. `has_key()`
|
You can't tell the type of objects by reading the method names (unless the
|
||||||
means a dictionary). This is also an advantage.
|
variable has type annotations). This is also an advantage.
|
||||||
|
|
||||||
<a id="s2.8.4-decision"></a>
|
<a id="s2.8.4-decision"></a>
|
||||||
<a id="284-decision"></a>
|
<a id="284-decision"></a>
|
||||||
|
@ -726,7 +726,6 @@ container while iterating over it.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
Yes: for key in adict: ...
|
Yes: for key in adict: ...
|
||||||
if key not in adict: ...
|
|
||||||
if obj in alist: ...
|
if obj in alist: ...
|
||||||
for line in afile: ...
|
for line in afile: ...
|
||||||
for k, v in adict.items(): ...
|
for k, v in adict.items(): ...
|
||||||
|
@ -734,7 +733,6 @@ Yes: for key in adict: ...
|
||||||
|
|
||||||
```python
|
```python
|
||||||
No: for key in adict.keys(): ...
|
No: for key in adict.keys(): ...
|
||||||
if not adict.has_key(key): ...
|
|
||||||
for line in afile.readlines(): ...
|
for line in afile.readlines(): ...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -964,7 +962,7 @@ Yes: def foo(a, b=None):
|
||||||
Yes: def foo(a, b: Optional[Sequence] = None):
|
Yes: def foo(a, b: Optional[Sequence] = None):
|
||||||
if b is None:
|
if b is None:
|
||||||
b = []
|
b = []
|
||||||
Yes: def foo(a, b: Sequence = ()): # Empty tuple OK since tuples are immutable
|
Yes: def foo(a, b: Sequence = ()): # Empty tuple OK since tuples are immutable.
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -978,7 +976,7 @@ No: def foo(a, b=time.time()): # The time the 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...
|
||||||
...
|
...
|
||||||
No: def foo(a, b: Mapping = {}): # Could still get passed to unchecked code
|
No: def foo(a, b: Mapping = {}): # Could still get passed to unchecked code.
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -1294,7 +1292,7 @@ more discussion.
|
||||||
Never use `staticmethod` unless forced to in order to integrate with an API
|
Never use `staticmethod` unless forced to in order to integrate with an API
|
||||||
defined in an existing library. Write a module level function instead.
|
defined in an existing library. Write a module level function instead.
|
||||||
|
|
||||||
Use `classmethod` only when writing a named constructor or a class-specific
|
Use `classmethod` only when writing a named constructor, or a class-specific
|
||||||
routine that modifies necessary global state such as a process-wide cache.
|
routine that modifies necessary global state such as a process-wide cache.
|
||||||
|
|
||||||
<a id="s2.18-threading"></a>
|
<a id="s2.18-threading"></a>
|
||||||
|
@ -1659,27 +1657,27 @@ No: if (x):
|
||||||
|
|
||||||
Indent your code blocks with *4 spaces*.
|
Indent your code blocks with *4 spaces*.
|
||||||
|
|
||||||
Never use tabs or mix tabs and spaces. In cases of implied line continuation,
|
Never use tabs. Implied line continuation should align wrapped elements
|
||||||
you should align wrapped elements either vertically, as per the examples in the
|
vertically (see [line length examples](#s3.2-line-length)), or use a hanging
|
||||||
[line length](#s3.2-line-length) section; or using a hanging indent of 4 spaces,
|
4-space indent. Closing (round, square or curly) brackets can be placed at the
|
||||||
in which case there should be nothing after the open parenthesis or bracket on
|
end of the expression, or on separate lines, but then should be indented the
|
||||||
the first line.
|
same as the line with the corresponding opening bracket.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
Yes: # Aligned with opening delimiter
|
Yes: # Aligned with opening delimiter.
|
||||||
foo = long_function_name(var_one, var_two,
|
foo = long_function_name(var_one, var_two,
|
||||||
var_three, var_four)
|
var_three, var_four)
|
||||||
meal = (spam,
|
meal = (spam,
|
||||||
beans)
|
beans)
|
||||||
|
|
||||||
# Aligned with opening delimiter in a dictionary
|
# Aligned with opening delimiter in a dictionary.
|
||||||
foo = {
|
foo = {
|
||||||
'long_dictionary_key': value1 +
|
'long_dictionary_key': value1 +
|
||||||
value2,
|
value2,
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
|
|
||||||
# 4-space hanging indent; nothing on first line
|
# 4-space hanging indent; nothing on first line.
|
||||||
foo = long_function_name(
|
foo = long_function_name(
|
||||||
var_one, var_two, var_three,
|
var_one, var_two, var_three,
|
||||||
var_four)
|
var_four)
|
||||||
|
@ -1687,7 +1685,18 @@ Yes: # Aligned with opening delimiter
|
||||||
spam,
|
spam,
|
||||||
beans)
|
beans)
|
||||||
|
|
||||||
# 4-space hanging indent in a dictionary
|
# 4-space hanging indent; nothing on first line,
|
||||||
|
# closing parenthesis on a new line.
|
||||||
|
foo = long_function_name(
|
||||||
|
var_one, var_two, var_three,
|
||||||
|
var_four
|
||||||
|
)
|
||||||
|
meal = (
|
||||||
|
spam,
|
||||||
|
beans,
|
||||||
|
)
|
||||||
|
|
||||||
|
# 4-space hanging indent in a dictionary.
|
||||||
foo = {
|
foo = {
|
||||||
'long_dictionary_key':
|
'long_dictionary_key':
|
||||||
long_dictionary_value,
|
long_dictionary_value,
|
||||||
|
@ -1696,18 +1705,18 @@ Yes: # Aligned with opening delimiter
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
No: # Stuff on first line forbidden
|
No: # Stuff on first line forbidden.
|
||||||
foo = long_function_name(var_one, var_two,
|
foo = long_function_name(var_one, var_two,
|
||||||
var_three, var_four)
|
var_three, var_four)
|
||||||
meal = (spam,
|
meal = (spam,
|
||||||
beans)
|
beans)
|
||||||
|
|
||||||
# 2-space hanging indent forbidden
|
# 2-space hanging indent forbidden.
|
||||||
foo = long_function_name(
|
foo = long_function_name(
|
||||||
var_one, var_two, var_three,
|
var_one, var_two, var_three,
|
||||||
var_four)
|
var_four)
|
||||||
|
|
||||||
# No hanging indent in a dictionary
|
# No hanging indent in a dictionary.
|
||||||
foo = {
|
foo = {
|
||||||
'long_dictionary_key':
|
'long_dictionary_key':
|
||||||
long_dictionary_value,
|
long_dictionary_value,
|
||||||
|
@ -2512,25 +2521,27 @@ documentation must explain clearly how resource lifetime is managed.
|
||||||
Use `TODO` comments for code that is temporary, a short-term solution, or
|
Use `TODO` comments for code that is temporary, a short-term solution, or
|
||||||
good-enough but not perfect.
|
good-enough but not perfect.
|
||||||
|
|
||||||
A `TODO` comment begins with the string `TODO` in all caps and a parenthesized
|
A `TODO` comment begins with the word `TODO` in all caps, and a parenthesized
|
||||||
name, e-mail address, or other identifier
|
context identifier. Ideally a bug reference, sometimes a username. A bug
|
||||||
of the person or issue with the best context about the problem. This is followed
|
reference like `TODO(https://crbug.com/bug_id_number):` is
|
||||||
by an explanation of what there is to do.
|
preferable, because bugs are tracked and have follow-up comments, whereas
|
||||||
|
individuals move around and may lose context over time. The `TODO` is followed by an explanation of
|
||||||
|
what there is to do.
|
||||||
|
|
||||||
The purpose is to have a consistent `TODO` format that can be searched to find
|
The purpose is to have a consistent `TODO` format that can be searched to find
|
||||||
out how to get more details. A `TODO` is not a commitment that the person
|
out how to get more details. A `TODO` is not a commitment that the person
|
||||||
referenced will fix the problem. Thus when you create a
|
referenced will fix the problem. Thus when you create a `TODO` with a username,
|
||||||
`TODO`, it is almost always your name
|
it is almost always your *own* username that is given.
|
||||||
that is given.
|
|
||||||
|
|
||||||
```python
|
```python
|
||||||
# TODO(kl@gmail.com): Use a "*" here for string repetition.
|
# TODO(crbug.com/192795): Investigate cpufreq optimizations.
|
||||||
# TODO(Zeke) Change this to use relations.
|
# TODO(yourusername): File an issue and use a '*' for repetition.
|
||||||
```
|
```
|
||||||
|
|
||||||
If your `TODO` is of the form "At a future date do something" make sure that you
|
If your `TODO` is of the form "At a future date do something" make sure that you
|
||||||
either include a very specific date ("Fix by November 2009") or a very specific
|
either include a very specific date ("Fix by November 2009") or a very specific
|
||||||
event ("Remove this code when all clients can handle XML responses.").
|
event ("Remove this code when all clients can handle XML responses.") that
|
||||||
|
future code maintainers will comprehend.
|
||||||
|
|
||||||
<a id="s3.13-imports-formatting"></a>
|
<a id="s3.13-imports-formatting"></a>
|
||||||
<a id="313-imports-formatting"></a>
|
<a id="313-imports-formatting"></a>
|
||||||
|
@ -2710,7 +2721,7 @@ change in complexity.
|
||||||
`send_acronym_via_https`.
|
`send_acronym_via_https`.
|
||||||
|
|
||||||
|
|
||||||
Function names, variable names, and filenames should be descriptive; eschew
|
Function names, variable names, and filenames should be descriptive; avoid
|
||||||
abbreviation. In particular, do not use abbreviations that are ambiguous or
|
abbreviation. In particular, do not use abbreviations that are ambiguous or
|
||||||
unfamiliar to readers outside your project, and do not abbreviate by deleting
|
unfamiliar to readers outside your project, and do not abbreviate by deleting
|
||||||
letters within a word.
|
letters within a word.
|
||||||
|
@ -2969,7 +2980,7 @@ the function into smaller and more manageable pieces.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(cls: Type[T]) -> T:
|
def create(cls: Type[_T]) -> _T:
|
||||||
return cls()
|
return cls()
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -2999,12 +3010,16 @@ the function into smaller and more manageable pieces.
|
||||||
Try to follow the existing [indentation](#indentation) rules.
|
Try to follow the existing [indentation](#indentation) rules.
|
||||||
|
|
||||||
After annotating, many function signatures will become "one parameter per line".
|
After annotating, many function signatures will become "one parameter per line".
|
||||||
|
To ensure the return type is also given its own line, a comma can be placed
|
||||||
|
after the last parameter.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def my_method(self,
|
def my_method(
|
||||||
|
self,
|
||||||
first_var: int,
|
first_var: int,
|
||||||
second_var: Foo,
|
second_var: Foo,
|
||||||
third_var: Optional[Bar]) -> int:
|
third_var: Optional[Bar],
|
||||||
|
) -> int:
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -3018,23 +3033,27 @@ def my_method(self, first_var: int) -> int:
|
||||||
```
|
```
|
||||||
|
|
||||||
If the combination of the function name, the last parameter, and the return type
|
If the combination of the function name, the last parameter, and the return type
|
||||||
is too long, indent by 4 in a new line.
|
is too long, indent by 4 in a new line. When using line breaks, prefer putting
|
||||||
|
each parameter and the return type on their own lines and aligning the closing
|
||||||
```python
|
parenthesis with the `def`:
|
||||||
def my_method(
|
|
||||||
self, first_var: int) -> tuple[MyLongType1, MyLongType1]:
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
When the return type does not fit on the same line as the last parameter, the
|
|
||||||
preferred way is to indent the parameters by 4 on a new line and align the
|
|
||||||
closing parenthesis with the `def`.
|
|
||||||
|
|
||||||
```python
|
```python
|
||||||
Yes:
|
Yes:
|
||||||
def my_method(
|
def my_method(
|
||||||
self, other_arg: Optional[MyLongType]
|
self,
|
||||||
) -> dict[OtherLongType, MyLongType]:
|
other_arg: Optional[MyLongType],
|
||||||
|
) -> tuple[MyLongType1, MyLongType1]:
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
Optionally, the return type may be put on the same line as the last parameter:
|
||||||
|
|
||||||
|
```python
|
||||||
|
Okay:
|
||||||
|
def my_method(
|
||||||
|
self,
|
||||||
|
first_var: int,
|
||||||
|
second_var: int) -> dict[OtherLongType, MyLongType]:
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -3045,7 +3064,7 @@ opening one, but this is less readable.
|
||||||
```python
|
```python
|
||||||
No:
|
No:
|
||||||
def my_method(self,
|
def my_method(self,
|
||||||
other_arg: Optional[MyLongType]
|
other_arg: Optional[MyLongType],
|
||||||
) -> dict[OtherLongType, MyLongType]:
|
) -> dict[OtherLongType, MyLongType]:
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
@ -3059,7 +3078,8 @@ def my_method(
|
||||||
first_var: tuple[list[MyLongType1],
|
first_var: tuple[list[MyLongType1],
|
||||||
list[MyLongType2]],
|
list[MyLongType2]],
|
||||||
second_var: list[dict[
|
second_var: list[dict[
|
||||||
MyLongType3, MyLongType4]]) -> None:
|
MyLongType3, MyLongType4]],
|
||||||
|
) -> None:
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -3176,8 +3196,8 @@ long:
|
||||||
<!-- Annotate below with `typing.TypeAlias` for 3.10. -->
|
<!-- Annotate below with `typing.TypeAlias` for 3.10. -->
|
||||||
|
|
||||||
```python
|
```python
|
||||||
_ShortName = module_with_long_name.TypeWithLongName
|
_LossAndGradient = tuple[tf.Tensor, tf.Tensor]
|
||||||
ComplexMap = Mapping[str, list[tuple[int, int]]]
|
ComplexTFMap = Mapping[str, _LossAndGradient]
|
||||||
```
|
```
|
||||||
|
|
||||||
Other examples are complex nested types and multiple return variables from a
|
Other examples are complex nested types and multiple return variables from a
|
||||||
|
|
Loading…
Reference in New Issue
Block a user