Last active
August 12, 2024 21:18
-
-
Save nafisk/8594e7c0eb4d97aea9e17447dbee7b40 to your computer and use it in GitHub Desktop.
Revisions
-
nafisk revised this gist
Aug 12, 2024 . 1 changed file with 386 additions and 38 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,14 +2,37 @@ ## π Code Layout - **Indentation**: Use 4 spaces per indentation level. Continuation lines should align with the opening delimiter or use a hanging indent. Hanging indents should not have arguments on the first line and should further indent to distinguish from the rest. ``` # Correct: def long_function_name(var_one, var_two, var_three, var_four): print(var_one) # Correct (hanging indent): def long_function_name( var_one, var_two, var_three, var_four): print(var_one) # Wrong: def long_function_name(var_one, var_two, var_three, var_four): print(var_one) ``` - **Tabs or Spaces**: Spaces are preferred over tabs for indentation. Mixing tabs and spaces is disallowed. ``` # Correct: if True: print("Spaces for indentation") # Wrong: if True: β print("Tabs for indentation") ``` - **Maximum Line Length**: Limit lines to 79 characters, and 72 characters for comments and docstrings. For teams preferring longer lines, the limit can be extended to 99 characters, provided comments and docstrings are still wrapped at 72 characters. ``` # Correct: comment = "This is an example within the length limit." @@ -18,18 +41,35 @@ long_comment = "This line exceeds the recommended maximum length, which is discouraged." ``` - **Blank Lines**: Surround top-level function and class definitions with two blank lines. Use a single blank line to separate method definitions inside a class. Extra blank lines can be used sparingly to separate related code sections. ``` # Correct: class MyClass: def method(self): pass # Wrong: class MyClass: def method(self): pass ``` - **Source File Encoding**: Always use UTF-8 encoding. Non-ASCII characters should be used sparingly, preferably only for human names or specific data. ``` # Correct: # -*- coding: utf-8 -*- author = "JosΓ©" # Wrong: author = "Jos\351" # Non-UTF-8 encoding ``` ## π¦ Imports - **Import Format**: Imports should be on separate lines. Group imports in the following order: standard library imports, third-party imports, and local imports. ``` # Correct: import os @@ -38,21 +78,66 @@ from flask import Flask from mymodule import myfunction # Wrong: import sys, os ``` - **Absolute Imports**: Absolute imports are recommended for clarity and better error handling. Explicit relative imports are acceptable in some cases, particularly in complex package layouts. ``` # Correct: from mymodule import myfunction # Also Correct (for complex layouts): from .mymodule import myfunction ``` - **Wildcard Imports**: Wildcard imports should generally be avoided as they make it unclear which names are present in the namespace. ``` # Correct: from math import pi # Wrong: from math import * # Wrong: from mymodule import * ``` ## π§© Module Level Dunder Names - **Placement**: Module-level βdundersβ (e.g., `__all__`, `__author__`, `__version__`) should appear after the module docstring but before any import statements, except for `from __future__` imports. ``` """ This is the example module. """ from __future__ import print_function __all__ = ['foo', 'bar'] __version__ = '1.0' __author__ = 'Your Name' import os ``` ## π String Quotes - **Consistency**: Single and double quotes are equivalent in Python; choose one and stick with it. Use triple double quotes for docstrings to align with PEP 257. ``` # Correct: name = "John" name = 'John' # Correct (docstring): def foo(): """This is a docstring.""" pass ``` ## βͺ Whitespace in Expressions and Statements - **Avoid Extraneous Whitespace**: Avoid unnecessary whitespace inside parentheses, brackets, braces, and before commas, colons, or semicolons. ``` # Correct: spam(ham[1], {eggs: 2}) @@ -61,7 +146,7 @@ spam( ham[ 1 ], { eggs: 2 } ) ``` - **Binary Operators**: Surround binary operators with a single space on both sides, except when used for alignment. ``` # Correct: x = 1 + 2 @@ -70,7 +155,7 @@ x=1+2 ``` - **Spacing for Matrix Brackets**: In slices, treat colons as binary operators, with equal spacing on either side. In extended slices with omitted parameters, omit the space around colons: ``` # Correct: ham[1:9], ham[1:9:3] @@ -79,71 +164,151 @@ ham[1: 9], ham[1 :9] ``` - **Function Calls and Indexing**: Do not add space immediately before the open parenthesis that starts the argument list of a function call or indexing/slicing: ``` # Correct: spam(1) dct['key'] = lst[index] # Wrong: spam (1) dct ['key'] = lst [index] ``` - **Assignment Operators**: Use a single space around assignment operators (`=`) for assignments, except when aligning multiple assignments to improve readability: ``` # Correct: x = 1 y = 2 # Wrong: x = 1 y = 2 ``` ## π Comments - **Block Comments**: Use block comments to explain sections of code, formatted as complete sentences. Each line of a block comment starts with a `#` and a single space. ``` # Correct: # This block comment explains the following code section. x = x + 1 # Wrong: #This block comment is not properly formatted. x = x + 1 ``` - **Inline Comments**: Use inline comments sparingly, separating them from the code by at least two spaces. They should not state the obvious. ``` # Correct: x = x + 1 # Increment x # Wrong: x = x + 1 #Increment x # Wrong (obvious): x = x + 1 # Add one to x ``` - **Documentation Strings**: Follow PEP 257 for docstring conventions. Write docstrings for all public modules, functions, classes, and methods. Multiline docstrings should have the closing `"""` on a line by itself. ``` # Correct: def foo(): """ This is a multiline docstring. It describes the function's purpose. """ pass # Wrong: def foo(): """This is a one-line docstring.""" pass ``` ## π€ Naming Conventions - **Descriptive Names**: Choose descriptive names that convey the purpose of the variable, function, or class. ``` # Correct: def calculate_area(radius): pass # Wrong: def foo(x): pass ``` - **Case Styles**: Use `lower_case_with_underscores` for functions and variables, `CapWords` (CamelCase) for classes, and `UPPER_CASE_WITH_UNDERSCORES` for constants. ``` # Correct: def my_function(): my_variable = 10 class MyClass: pass MAX_OVERFLOW = 100 ``` - **Underscores**: Use a single leading underscore for non-public methods and instance variables. Use double leading underscores to invoke name mangling for attributes intended to be private in subclasses. ``` # Correct: class MyClass: def _private_method(self): pass class MyClass: def __private_method(self): pass ``` ## π§ Programming Recommendations - **Comparison Operators**: Use `is` or `is not` for comparisons to `None`, and `isinstance()` for type checks. ``` # Correct: if obj is None: pass if isinstance(obj, int): pass # Wrong: if obj == None: pass if type(obj) is int: pass ``` - **Boolean Values**: Do not compare boolean values to `True` or `False` using `==`: ``` # Correct: if greeting: pass # Wrong: if greeting == True: pass ``` - **Return Statements**: Be consistent with return statements within a function. If a function returns a value in some cases, ensure all paths return a value, explicitly using `return None` when necessary. ``` # Correct: def foo(x): if x >= 0: return x return None # Wrong: def foo(x): if x >= 0: return x ``` - **Lambda Expressions**: Prefer `def` over `lambda` for function definitions, as it provides better readability and debugging information. ``` # Correct: def add(x, y): return x + y @@ -152,14 +317,197 @@ add = lambda x, y: x + y ``` ## π§ Programming Recommendations (continued) - **Exception Handling**: Catch specific exceptions rather than using a bare `except:` clause. Use exception chaining appropriately with `raise X from Y`. ``` # Correct: try: result = x / y except ZeroDivisionError: print("Division by zero is not allowed.") raise # Correct (chaining): try: value = some_function() except ValueError as e: raise CustomError("An error occurred") from e # Wrong: try: result = x / y except: print("An error occurred.") ``` - **Context Managers**: Use `with` statements for managing resources to ensure proper cleanup. ``` # Correct: with open('file.txt', 'r') as file: content = file.read() # Wrong: file = open('file.txt', 'r') try: content = file.read() finally: file.close() ``` - **Function Annotations**: Follow PEP 484 for function annotations. Use PEP 526 for variable annotations, ensuring proper spacing around colons and equal signs: ``` # Correct: def munge(input: AnyStr = None): pass code: int = 123 # Wrong: def munge(input:AnyStr=None): pass code:int = 123 ``` ## π οΈ Designing for Inheritance - **Public vs. Non-Public**: Distinguish between public and non-public attributes in classes. Public attributes should be accessible and stable, while non-public attributes are subject to change and should be marked with leading underscores. ``` # Correct: class MyClass: def public_method(self): pass def _non_public_method(self): pass ``` - **Name Mangling**: Use double leading underscores to avoid name clashes in subclasses, though be cautious of potential drawbacks in debugging and introspection. ``` # Correct: class MyClass: def __private_method(self): pass class SubClass(MyClass): def __private_method(self): pass # This will not override MyClass's __private_method ``` ## π Public and Internal Interfaces - **Public Interfaces**: Documented interfaces are considered public unless explicitly marked otherwise. Use the `__all__` attribute to define the public API of a module. ``` # Correct: __all__ = ['public_function', 'PublicClass'] def public_function(): pass class PublicClass: pass def _internal_function(): pass ``` - **Internal Interfaces**: Prefix internal names with a single leading underscore to indicate that they are not part of the public API. ``` # Correct: _internal_variable = 42 def _internal_function(): pass ``` - **Imported Names**: Imported names should be considered an implementation detail. Other modules should not rely on indirect access to such names unless they are explicitly documented as part of the public API. ``` # Correct: from mymodule import _internal_function # Usage only within the module that imported it: _internal_function() ``` ## π» Programming Practices - **String Methods**: Use `.startswith()` and `.endswith()` instead of slicing for checking prefixes or suffixes. ``` # Correct: if filename.startswith('file_'): pass # Wrong: if filename[:5] == 'file_': pass ``` - **Type Comparisons**: Use `isinstance()` for type comparisons rather than comparing types directly: ``` # Correct: if isinstance(obj, int): pass # Wrong: if type(obj) is int: pass ``` - **Sequences**: For sequences (strings, lists, tuples), use the fact that empty sequences are false: ``` # Correct: if not seq: pass # Wrong: if len(seq) == 0: pass ``` - **Avoid Trailing Whitespace**: Avoid trailing whitespace as it can be confusing and lead to subtle bugs. ``` # Correct: message = "Hello, World!" # Wrong (note the trailing space after the exclamation point): message = "Hello, World! " ``` - **Return in Finally Blocks**: Avoid using `return`, `break`, or `continue` in a `finally` block as it can interfere with exception propagation. ``` # Wrong: def foo(): try: return 1 finally: return 2 # This will override the previous return ``` - **Consistent Returns**: Be consistent in the use of `return` statements; if any `return` in a function returns a value, all should, and `return None` should be explicit when no value is returned. ``` # Correct: def foo(x): if x >= 0: return x return None # Wrong: def foo(x): if x >= 0: return x ``` - **Use of Annotations**: Follow PEP 484 for function and variable annotations. Variable annotations should have proper spacing around colons and equal signs, consistent with the style guide. ``` # Correct: def add(a: int, b: int) -> int: return a + b x: int = 10 # Wrong: def add(a:int,b:int)->int: return a + b x:int=10 -
nafisk created this gist
Aug 12, 2024 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,165 @@ # PEP 8 β Style Guide for Python Code ## π Code Layout - **Indentation**: Use 4 spaces per indentation level. No tabs! ``` def example(): if True: return ``` - **Line Length**: Limit lines to 79 characters for code, and 72 characters for comments and docstrings. ``` # Correct: comment = "This is an example within the length limit." # Wrong: long_comment = "This line exceeds the recommended maximum length, which is discouraged." ``` - **Blank Lines**: Use 2 blank lines around top-level functions and classes, and 1 blank line around method definitions inside a class. ``` # Correct: class MyClass: def method(self): pass ``` ## π¦ Imports - **Order and Grouping**: Group imports into three categories: standard library imports, third-party imports, and local imports. Maintain this order, with a blank line between each group. ``` # Correct: import os import sys from flask import Flask from mymodule import myfunction ``` - **Import Format**: Each import should be on a separate line. ``` # Correct: import os import sys # Wrong: import sys, os ``` ## βͺ Whitespace - **Avoid Extraneous Whitespace**: Avoid unnecessary spaces around parentheses, brackets, and braces. ``` # Correct: spam(ham[1], {eggs: 2}) # Wrong: spam( ham[ 1 ], { eggs: 2 } ) ``` - **Binary Operators**: Use a single space around binary operators like `=`, `+`, `-`, `*`, `/`, etc. ``` # Correct: x = 1 + 2 # Wrong: x=1+2 ``` - **Spacing in Slices**: Treat colons in slices as binary operators, with spaces on both sides. In extended slices, omit the space when parameters are missing. ``` # Correct: ham[1:9], ham[1:9:3] # Wrong: ham[1: 9], ham[1 :9] ``` ## π Comments and Docstrings - **Block Comments**: Use full sentences, and align comments with the code they describe. ``` # This block comment explains the following code section. x = x + 1 ``` - **Inline Comments**: Place inline comments on the same line as the statement they describe, separated by at least two spaces. ``` # Correct: x = x + 1 # Increment x # Wrong: x = x + 1 #Increment x ``` - **Docstrings**: Write docstrings for all public modules, functions, classes, and methods. Use triple double quotes, and keep them concise. ``` # Correct: def foo(): """Return a foobang.""" return "foo" ``` ## π€ Naming Conventions - **Variables and Functions**: Use `lower_case_with_underscores` for variable and function names. ``` def my_function(): my_variable = 10 ``` - **Constants**: Use `UPPER_CASE_WITH_UNDERSCORES` for constant values. ``` MAX_OVERFLOW = 100 ``` - **Classes**: Use `CapWords` (CamelCase) for class names. ``` class MyClass: pass ``` ## π§ Best Practices - **Comparison to `None`**: Use `is` or `is not` when comparing to `None`. ``` # Correct: if obj is None: # Wrong: if obj == None: ``` - **Type Checking**: Use `isinstance()` for type comparisons rather than comparing types directly. ``` # Correct: if isinstance(obj, int): # Wrong: if type(obj) is int: ``` - **Avoid `lambda` for Function Assignment**: Prefer `def` statements over `lambda` when assigning functions to variables. ``` # Correct: def add(x, y): return x + y # Wrong: add = lambda x, y: x + y ``` ## π Public vs. Non-Public Attributes - **Public Attributes**: Accessible and stable, with no leading underscores. - **Non-Public Attributes**: Subject to change, indicated by a single leading underscore. - **Name Mangling**: Use double leading underscores to avoid name clashes in subclasses, but be mindful of potential debugging challenges. ``` class MyClass: def __private_method(self): pass ```