python
What I do
I help you write Python code that follows professional style guide conventions. This includes:
- Enforcing naming conventions (snake_case, PascalCase, UPPER_CASE)
- Applying proper docstring formatting (module, class, function, method docstrings)
- Managing imports correctly (full package paths, proper ordering)
- Implementing type annotations following best practices
- Following line length and indentation rules
- Using proper exception handling patterns
- Writing clean, readable code that matches professional standards
When to use me
Use this skill when:
- Writing new Python code that should follow style guide conventions
- Refactoring existing Python code to match best practices
- Reviewing Python code for style compliance
- Adding documentation to Python modules, classes, or functions
- Setting up type hints for Python code
- Organizing imports in Python files
Key style rules I enforce
Naming Conventions
- Modules:
module_name.py(lowercase with underscores) - Packages:
package_name(lowercase, no underscores preferred) - Classes:
ClassName(PascalCase) - Functions:
function_name()(lowercase with underscores) - Variables:
variable_name(lowercase with underscores) - Constants:
CONSTANT_NAME(uppercase with underscores) - Private attributes:
_private_var(leading underscore) - Internal globals:
_internal_global(leading underscore) - Strongly private attributes:
__secret_var(double leading underscore for name mangling)
Important: For strongly private attributes that should be protected via name mangling, always use double underscore prefix:
class MyClass:
def __init__(self):
# Public attribute
self.public_var: str = "visible"
# Protected attribute (convention only)
self._protected_var: str = "use with care"
# Private attribute (name mangled to _MyClass__secret)
self.__secret: str = "truly private"
Imports
Use full package paths:
# Good
from absl import flags
from doctor.who import jodie
# Bad
import jodie # Ambiguous
Import order:
- Standard library imports
- Third-party imports
- Local application imports
Docstrings
Always use triple-quoted strings """ format.
Function docstring template:
def fetch_smalltable_rows(
table_handle: smalltable.Table,
keys: Sequence[bytes | str],
require_all_keys: bool = False,
) -> Mapping[bytes, tuple[str, ...]]:
"""Fetches rows from a Smalltable.
Retrieves rows pertaining to the given keys from the Table instance
represented by table_handle. String keys will be UTF-8 encoded.
Args:
table_handle: An open smalltable.Table instance.
keys: A sequence of strings representing the key of each table
row to fetch. String keys will be UTF-8 encoded.
require_all_keys: If True only rows with values set for all keys will be
returned.
Returns:
A dict mapping keys to the corresponding table row data
fetched. Each row is represented as a tuple of strings. For
example:
{b'Serak': ('Rigel VII', 'Preparer'),
b'Zim': ('Irk', 'Invader'),
b'Lrrr': ('Omicron Persei 8', 'Emperor')}
Returned keys are always bytes. If a key from the keys argument is
missing from the dictionary, then that row was not found in the
table (and require_all_keys must have been False).
Raises:
IOError: An error occurred accessing the smalltable.
"""
Class docstring template:
class SampleClass:
"""Summary of class here.
Longer class information...
Longer class information...
Attributes:
likes_spam: A boolean indicating if we like SPAM or not.
eggs: An integer count of the eggs we have laid.
"""
def __init__(self, likes_spam: bool = False):
"""Initializes the instance based on spam preference.
Args:
likes_spam: Defines if instance exhibits this preference.
"""
self.likes_spam = likes_spam
self.eggs = 0
Module docstring template:
"""A one-line summary of the module or program, terminated by a period.
Leave one blank line. The rest of this docstring should contain an
overall description of the module or program. Optionally, it may also
contain a brief description of exported classes and functions and/or usage
examples.
Typical usage example:
foo = ClassFoo()
bar = foo.function_bar()
"""
Type Annotations
Always add type hints to function signatures:
def func(a: int) -> list[int]:
return [a * 2]
# For variables when type isn't obvious
a: SomeType = some_func()
# Use modern syntax (Python 3.10+)
def process(data: str | None = None) -> dict[str, int]:
pass
Important: Use capitalized type hints from typing module instead of built-in lowercase types:
from typing import Dict, List, Set, Tuple, Optional
# Good - using typing module
def process_users(users: List[str]) -> Dict[str, int]:
return {user: len(user) for user in users}
def get_config() -> Dict[str, List[int]]:
return {"ports": [8080, 8081]}
# Good - with Optional
def find_user(user_id: int) -> Optional[str]:
return None
# Bad - using built-in lowercase types (avoid)
def process_users(users: list[str]) -> dict[str, int]:
return {user: len(user) for user in users}
Note: While Python 3.9+ supports lowercase list, dict, etc., using the typing module variants (List, Dict) is preferred for consistency and broader compatibility.
Line Length and Formatting
- Maximum line length: 80 characters
- Use implicit line continuation with parentheses (not backslashes)
- Indent with 4 spaces (never tabs)
- Two blank lines between top-level definitions
- One blank line between method definitions
# Good
foo_bar(
self, width, height, color='black', design=None, x='foo',
emphasis=None, highlight=0
)
# Good
if (width == 0 and height == 0 and
color == 'red' and emphasis == 'strong'):
pass
# Bad - backslash continuation
if width == 0 and height == 0 and \
color == 'red' and emphasis == 'strong':
pass
Exception Handling
# Good
def connect_to_next_port(self, minimum: int) -> int:
"""Connects to the next available port.
Args:
minimum: A port value greater or equal to 1024.
Returns:
The new minimum port.
Raises:
ConnectionError: If no available port is found.
"""
if minimum < 1024:
raise ValueError(f'Min. port must be at least 1024, not {minimum}.')
port = self._find_next_port(minimum)
if port is None:
raise ConnectionError(
f'Could not connect to service on port {minimum} or higher.')
return port
Default Arguments
Never use mutable objects as default values:
# Good
def foo(a, b: list[int] | None = None):
if b is None:
b = []
# Bad
def foo(a, b: list[int] = []):
pass
Boolean Evaluations
Use implicit false when possible:
# Good
if not users:
print('no users')
if foo:
bar()
# Check for None explicitly
if x is None:
pass
# Bad
if len(users) == 0:
print('no users')
if foo != []:
bar()
Comprehensions
Keep them simple - optimize for readability:
# Good
result = [mapping_expr for value in iterable if filter_expr]
# Good
result = [
is_valid(metric={'key': value})
for value in interesting_iterable
if a_longer_filter_expression(value)
]
# Bad - multiple for clauses
result = [(x, y) for x in range(10) for y in range(5) if x * y > 10]
Loop Variables
Important: Always use underscore prefix for loop variables when you don't use the variable itself:
# Good - using underscore when variable is not used
for _user in users:
print("Processing a user")
send_notification()
for _item in items:
count += 1
# Good - using the variable
for user in users:
print(f"Processing {user.name}")
user.process()
# Bad - not using underscore when variable is unused
for user in users: # 'user' is never referenced
print("Processing a user")
This convention makes it immediately clear that the loop variable is intentionally unused.
Linting
- Run
pylinton all code - Suppress warnings with inline comments when appropriate:
def do_PUT(self): # WSGI name, so pylint: disable=invalid-name
pass
The Zen of Python
Follow these fundamental principles from PEP 20 (The Zen of Python):
- Beautiful is better than ugly - Write elegant, readable code
- Explicit is better than implicit - Be clear about what your code does
- Simple is better than complex - Favor straightforward solutions
- Complex is better than complicated - When complexity is needed, keep it organized
- Flat is better than nested - Avoid deep nesting when possible
- Sparse is better than dense - Use whitespace for readability
- Readability counts - Code is read more often than written
- Special cases aren't special enough to break the rules - Consistency matters
- Although practicality beats purity - Pragmatism over dogmatism when needed
- Errors should never pass silently - Handle exceptions explicitly
- In the face of ambiguity, refuse the temptation to guess - Be explicit
- There should be one-- and preferably only one --obvious way to do it - Favor the idiomatic approach
- Now is better than never - Don't overthink, start coding
- Although never is often better than right now - But plan before rushing
- If the implementation is hard to explain, it's a bad idea - Simplicity test
- If the implementation is easy to explain, it may be a good idea - Clarity indicator
- Namespaces are one honking great idea - Use them to organize code
Access these at any time by running:
import this
Key principles to remember:
- Explicit > Implicit
- Simple > Complex
- Readability counts
- One obvious way to do things
How I work
When you ask me to help with Python code, I will:
- Analyze the code for style violations
- Suggest specific improvements citing relevant style rules
- Rewrite code sections to match professional style
- Add proper docstrings following standard format
- Format imports, line lengths, and indentation correctly
- Apply type annotations where missing or incorrect
I prioritize readability and maintainability over brevity. When there's ambiguity, I'll ask clarifying questions about your specific use case.
References
- Full style guide: https://google.github.io/styleguide/pyguide.html
- PEP 8 (Python's general style guide): https://peps.python.org/pep-0008/
- PEP 257 (Docstring conventions): https://peps.python.org/pep-0257/
- Type hints (PEP 484): https://peps.python.org/pep-0484/
More from the-perfect-developer/the-perfect-opencode
html
Apply Google HTML style guide conventions to HTML code
21turso-libsql
This skill should be used when the user asks to "connect to Turso", "use libSQL", "set up a Turso database", "query Turso with TypeScript", or needs guidance on Turso Cloud, embedded replicas, or vector search with libSQL.
11alpinejs
This skill should be used when the user asks to "add Alpine.js", "create Alpine component", "use Alpine directives", "build interactive UI with Alpine", or needs guidance on Alpine.js development patterns and best practices.
10agent-configuration
This skill should be used when the user asks to "configure agents", "create a custom agent", "set up agent permissions", "customize agent behavior", "switch agents", or needs guidance on OpenCode agent system.
4git-hooks
This skill should be used when the user asks to "create git hooks", "set up pre-commit hooks", "configure git hooks", "add commit validation", "implement pre-push hooks", or needs guidance on Git hooks implementation, validation scripts, or hook best practices.
4json-style
This skill should be used when the user asks to "format JSON", "design JSON API", "write JSON response", "structure JSON data", or needs guidance on JSON naming conventions and best practices based on Google's JSON Style Guide.
4