用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/Objective-Arts/lens-dist --skill python-protocols命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
基于 SOC 职业分类
| name | python-protocols |
| description | Fluent Python - data model, protocols, dunder methods, Pythonic design |
Apply Luciano Ramalho's expertise from "Fluent Python." Master Python's data model, protocols, and the patterns that make code truly Pythonic.
Python's special methods (dunder methods) define how objects behave. Understanding them is the key to Pythonic code.
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return f'Vector({self.x!r}, {self.y!r})'
def __abs__(self):
return (self.x ** 2 + self.y ** 2) ** 0.5
def __bool__(self):
return bool(abs(self))
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
def __mul__(self, scalar):
return Vector(self.x * scalar, self.y * scalar)
# Now Vector works naturally with Python
v = Vector(3, 4)
abs(v) # 5.0
bool(v) # True
v + v # Vector(6, 8)
v * 3 # Vector(9, 12)
Python uses duck typing. Implement protocols (sets of methods) rather than inheriting from base classes.
# The Sequence protocol: __len__ and __getitem__
class Deck:
ranks = [str(n) for n in range(2, 11)] + list('JQKA')
suits = 'spades diamonds clubs hearts'.split()
def __init__(self):
self._cards = [Card(rank, suit)
for suit in self.suits
for rank in self.ranks]
def __len__(self):
return len(self._cards)
def __getitem__(self, position):
return self._cards[position]
# Now Deck supports: iteration, slicing, in, reversed, sorted
deck = Deck()
len(deck) # 52
deck[0] # Card(rank='2', suit='spades')
deck[-1] # Card(rank='A', suit='hearts')
deck[12::13] # Four aces
Card('Q', 'hearts') in deck # True
for card in deck:
(card)
# BAD: Default repr is useless
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
# >>> Point(3, 4)
# <Point object at 0x...>
# GOOD: Informative repr
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return f'{self.__class__.__name__}({self.x!r}, {self.y!r})'
# >>> Point(3, 4)
# Point(3, 4)
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
return self._radius
@radius.setter
def radius(self, value):
if value < 0:
raise ValueError('Radius must be positive')
self._radius = value
@property
def area(self):
return 3.14159 * self._radius ** 2
@property
def diameter(self):
return self._radius * 2
class Pixel:
__slots__ = ('x', 'y', 'color')
def __init__(self, x, y, color):
self.x = x
self.y = y
self.color = color
# Millions of Pixels? __slots__ saves significant memory
# Classes can be callable
class Averager:
def __init__(self):
self.series = []
def __call__(self, new_value):
self.series.append(new_value)
return sum(self.series) / len(self.series)
avg = Averager()
avg(10) # 10.0
avg(11) # 10.5
avg(12) # 11.0
class DatabaseConnection:
def __init__(self, connection_string):
self.connection_string = connection_string
self.connection = None
def __enter__(self):
self.connection = connect(self.connection_string)
return self.connection
def __exit__(self, exc_type, exc_val, exc_tb):
self.connection.close()
return False # Don't suppress exceptions
with DatabaseConnection('...') as conn:
conn.execute('SELECT ...')
| Protocol | Methods | Enables |
|---|---|---|
| Container | __contains__ | in operator |
| Sized | __len__ | len() |
| Iterable | __iter__ | for loops |
| Sequence | __getitem__, __len__ | Indexing, slicing, iteration |
| Mapping | __getitem__, __contains__, __iter__ | Dict-like access |
| Callable | __call__ | obj() syntax |
| Context Manager | __enter__, __exit__ | with statement |
| Hashable | __hash__, __eq__ | Dict keys, set members |
| Pattern | Ramalho Fix |
|---|---|
Bare class with no __repr__ | Always implement __repr__ |
| Getter/setter methods | Use @property |
isinstance() checks everywhere | Duck typing, protocols |
Inheriting from list/dict | Compose with delegation |
| Mutable default arguments | Use None and create in __init__ |
__repr__?@property?__hash__ consistent with __eq__?__slots__ used for memory-critical classes?"Pythonic code is not about tricks or idioms—it's about leveraging Python's data model. When you implement the right special methods, your objects integrate naturally with the language."