我试图模仿c#扩展的行为,例如针对Python类,该类暴露了一些包含缓存描述符的属性,这些属性返回各种命名元组的集合。
from collections import namedtuple
class Descriptor:
def __init__(self, func):
self.func = func
self.name = func.__name__
self.__doc__ = func.__doc__
def __get__(self, ctx, owner=None):
if ctx is None:
return self
result = self.func(ctx)
setattr(ctx, self.name, result)
return result
class Container(tuple):
def __new__(cls, seq):
return super().__new__(cls, seq)
def get(self, **kwargs):
"""Gets an item matching the specified criteria.
:param dict kwargs: One or more key value pairs of criteria to filter with.
:returns: The first item matching the given criteria or None.
"""
for item in self:
if all(getattr(item, k, None) == v for k, v in kwargs.items()):
return item
def where(self, **kwargs):
"""Gets all items matching the specified criteria.
:param dict kwargs: One or more key value pairs of criteria to filter with.
:returns: All items matching the given criteria or None.
"""
return Container((x for x in self if all(getattr(x, k, None) == v for k, v in kwargs.items())))
Item = namedtuple('Item', ('foo', 'bar', 'baz'))
class Class:
@Descriptor
def prop(self):
result = [Item(x, x * 10, x * 100) for x in range(5)]
return Container(result)
c = Class()
for x in c.prop:
# Properties of Item are not available to introspection.
print(x.foo, x.bar)
y = c.prop
# Properties of y (get, where) are not available to introspection.
print(y.get(foo=1))
当迭代c.prop时,应调用基本元组方法,但内省不存在。
暗示Container类的添加方法的问题得到/这个单个类包含各种类型,如本机元组。对于为每个命名元组创建具有适当文档字符串的容器没有用。
我在pycharm和ipython中测试。一旦在调用之后对象被实例化,Ipython就会收集一些洞察力,但这还不够。
如何构建促进这一想法的通用容器?