mirror of
				https://github.com/pocketpy/pocketpy
				synced 2025-10-31 08:50:17 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			222 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			222 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| ---
 | ||
| icon: book
 | ||
| order: -5
 | ||
| label: Coding Style Guide
 | ||
| ---
 | ||
| 
 | ||
| ## Indentation
 | ||
| 
 | ||
| Use four spaces for indentation. Do not use `TAB`.
 | ||
| 
 | ||
| ## Strings
 | ||
| 
 | ||
| ```python
 | ||
| # Prefer single quotes for strings
 | ||
| s = 'this is a string'
 | ||
| 
 | ||
| # Use double quotes only if the string itself contains a single quote
 | ||
| s = "this ' is single quote"
 | ||
| ```
 | ||
| 
 | ||
| ## Docstrings
 | ||
| 
 | ||
| Always use triple quotes for docstrings.
 | ||
| 
 | ||
| ```python
 | ||
| def f():
 | ||
|     """This is a multi-line docstring.
 | ||
| 
 | ||
|     Here is some content. Docstrings partially support Markdown.
 | ||
|     """
 | ||
| 
 | ||
| def g():
 | ||
|     """This is a single-line docstring."""
 | ||
| ```
 | ||
| 
 | ||
| Use natural language to describe the function's purpose. Do not enumerate each parameter and return value.
 | ||
| 
 | ||
| ```python
 | ||
| # Correct
 | ||
| def add(a: int, b: int):
 | ||
|     """Add two integers `a` and `b`."""
 | ||
| 
 | ||
| # Incorrect
 | ||
| def add(a: int, b: int):
 | ||
|     """
 | ||
|     @param a, the first argument
 | ||
|     @param b, the second argument
 | ||
|     @return, the result of a + b
 | ||
|     """
 | ||
| ```
 | ||
| 
 | ||
| ## Spaces
 | ||
| 
 | ||
| ```python
 | ||
| # Add a space after `,` or `:`
 | ||
| a, b = 1, 2
 | ||
| c = [1, 2, 3]
 | ||
| d = {'key': 'value'}
 | ||
| 
 | ||
| # Spaces may be added around operators
 | ||
| res = 1 + 2
 | ||
| if res < 2: pass
 | ||
| # Spaces can also be selectively added to indicate operator precedence
 | ||
| x = x * 2 - 1
 | ||
| hypot2 = x * x + y * y
 | ||
| c = (a + b) * (a - b)
 | ||
| 
 | ||
| # Add a space after `:` in type annotations
 | ||
| def f(a: int, b: float): ...
 | ||
| def g() -> int: ...
 | ||
| 
 | ||
| # Add spaces around `=` when specifying default values in function parameters
 | ||
| def f(a: int = 1, b: int | None = None): ...
 | ||
| # However, omit spaces if the parameter has no type annotation
 | ||
| def f(a=1, b=2): pass
 | ||
| 
 | ||
| # Do not add spaces in keyword arguments when calling functions
 | ||
| print(1, 2, 3, end='', sep=',')
 | ||
| f(a=10, b=20)
 | ||
| ```
 | ||
| 
 | ||
| ## Naming Conventions
 | ||
| 
 | ||
| + Classes: `CapitalizedWords`
 | ||
| + Functions and variables: `lower_case_with_underscores`
 | ||
| + Constants and enums: `UPPER_CASE_WITH_UNDERSCORES` or `CapitalizedWords`
 | ||
| + Anonymous ordered variables: `_0`, `_1`, `_2`
 | ||
| + Discarded variables: `_`
 | ||
| + Some standard library functions: `lowercase`
 | ||
| 
 | ||
| Here are some commonly used naming conventions:
 | ||
| + `self`: The first parameter of an instance method
 | ||
| + `cls`: The first parameter of class methods and `__new__`
 | ||
| 
 | ||
| ### Using Abbreviations
 | ||
| 
 | ||
| Use abbreviations only for temporary variables and internal implementations.
 | ||
| 
 | ||
| Abbreviations should be well-established, include key syllables of the original word, and be immediately recognizable.
 | ||
| 
 | ||
| * `context` -> `ctx` (✔)
 | ||
| * `temporary` -> `tmp` (✔)
 | ||
| * `distribution` -> `dist` (✔)
 | ||
| * `visited` -> `vis` (❌)
 | ||
| 
 | ||
| ```python
 | ||
| # Incorrect: Using abbreviations in public function parameters
 | ||
| def some_pub_fn(ctx, req_id, data):
 | ||
|     pass
 | ||
| 
 | ||
| # Correct
 | ||
| def some_public_function(context, request_id, data):
 | ||
|     pass
 | ||
| ```
 | ||
| 
 | ||
| ### Using Precise Terminology
 | ||
| 
 | ||
| Naming should convey precise meanings, especially when multiple synonyms exist.
 | ||
| 
 | ||
| For example, `count`, `size`, and `length` all relate to quantity, but they have different nuances:
 | ||
| 
 | ||
| + `count`: Represents a counted value
 | ||
| + `length`: Represents the number of elements in a container
 | ||
| + `size`: Represents the byte size of an object
 | ||
| 
 | ||
| ```python
 | ||
| s = 'aaabc⭐'
 | ||
| count = s.count('a')
 | ||
| length = len(s)
 | ||
| size = len(s.encode())
 | ||
| 
 | ||
| print(f"{s!r} has a length of {length}, a size of {size} bytes, and contains {count} occurrences of 'a'")
 | ||
| # 'aaabc⭐' has a length of 6, a size of 8 bytes, and contains 3 occurrences of 'a'
 | ||
| ```
 | ||
| 
 | ||
| ### Using Professional Terminology
 | ||
| 
 | ||
| + For item quantities in a game: `quantity` is better than `item_count`
 | ||
| + For grid counts: `area` (meaning surface area) is better than `grid_count`
 | ||
| 
 | ||
| ### Avoiding Built-in Names
 | ||
| 
 | ||
| ```python
 | ||
| # Incorrect: Overwriting `builtins.map`
 | ||
| map = [[1, 2, 3], [4, 5, 6]]
 | ||
| # Incorrect: Overwriting `builtins.type`
 | ||
| type = some_thing.type
 | ||
| ```
 | ||
| 
 | ||
| ### Internal Functions and Classes
 | ||
| 
 | ||
| Use a single underscore `_` as a prefix for internal functions. Never use a double underscore `__` (except for magic methods).
 | ||
| 
 | ||
| ```python
 | ||
| def _internal_func():
 | ||
|     """This is an internal function."""
 | ||
| 
 | ||
| class _InternalClass:
 | ||
|     def _internal_f(self): pass
 | ||
| ```
 | ||
| 
 | ||
| ## Importing Modules
 | ||
| 
 | ||
| 1. Import standard library modules first.
 | ||
| 2. Then import third-party dependencies.
 | ||
| 3. Finally, import project-specific modules.
 | ||
| 
 | ||
| ```python
 | ||
| from typing import Any
 | ||
| from collections import deque
 | ||
| 
 | ||
| from array2d import array2d
 | ||
| 
 | ||
| from ..utils import logger
 | ||
| ```
 | ||
| 
 | ||
| ## Coding Practices
 | ||
| 
 | ||
| Use `is not` when checking for `None`. Do not explicitly compare with `True` or `False`.
 | ||
| 
 | ||
| ```python
 | ||
| # Correct
 | ||
| if x is not None: pass
 | ||
| 
 | ||
| # Incorrect
 | ||
| if x != None: pass
 | ||
| 
 | ||
| # Correct
 | ||
| x = True
 | ||
| if x: pass
 | ||
| if not x: pass
 | ||
| 
 | ||
| # Incorrect
 | ||
| if x == True: pass
 | ||
| if x is True: pass
 | ||
| if x != False: pass
 | ||
| ```
 | ||
| 
 | ||
| The `if` statement implicitly calls `bool()`, so it can be used to check if a container is empty.
 | ||
| 
 | ||
| ```python
 | ||
| not_empty_list = [1]
 | ||
| not_empty_string = '1'
 | ||
| truth = True
 | ||
| 
 | ||
| if not_empty_list:
 | ||
|     print('true value')
 | ||
| 
 | ||
| if not_empty_string:
 | ||
|     print('true value')
 | ||
| 
 | ||
| if truth:
 | ||
|     print('true value')
 | ||
| 
 | ||
| # Explicitly checking for emptiness is also valid
 | ||
| if len(not_empty_list) > 0: pass
 | ||
| ```
 | ||
| 
 | ||
| ## References
 | ||
| 
 | ||
| [PEP 8 – Style Guide for Python Code](https://peps.python.org/pep-0008/)
 |