好吧,这可能是一个非常愚蠢的问题而且可能不可能,或者我正在以一种扭曲的方式思考。所以,请考虑一下:
class MyClass:
def __init__(self, x):
self.x = x
self.y = self.x ** 2
class MyList:
def __init__(self, list):
self.list = list
def __iter__(self):
return iter(self.list)
foo = [MyClass(x=1), MyClass(x=2)]
bar = MyList(list=foo)
for i in bar:
print(i.x, i.y)
好的,这里我们有两个类:MyClass
只是非常普通的东西而且没什么特别的。它有两个实例属性:x
和y
。
另一方面,MyList
应该是一个定义迭代器的类,该迭代器只应包含第一个类MyClass
中的元素!
然后我创建了MyClass
的两个实例,将它们放在列表foo
中,并使用此列表创建MyList
(bar
)的实例。
现在,传递给MyList
的列表应该只包含MyClass
元素!我想要的是Python要意识到这个事实!当我编写一个迭代bar
内容的循环时,我希望Python知道bar
中的元素是MyClass
个对象。
我的程序目前的一个主要不便之处是Python没有意识到这一点,并且自动完成功能不起作用。换句话说:在循环中,当我写i.
时,我希望弹出所有可能的参数(在本例中为x
和y
)。我可以在Python中为MyList
定义一些魔术方法,使Python知道这个列表的内容吗?
答案 0 :(得分:3)
如果您使用的是PyCharm IDE,那么您可以这样做:
for i in bar:
assert isinstance(i, MyClass)
或者这个:
for i in bar: # type: MyClass
答案 1 :(得分:2)
在Python≥3.0中,您可以使用函数注释(PEP 3107)和PEP 0484的类型提示语义。虽然后一个提议仅在Python 3.5和will be provisional until the release of 3.6中被接受,但它在语法上向后兼容所有支持PEP 3107的Python版本,因此在任何3.x版本的Python中使用类型提示注释应at least not hurt。< SUP> [1]
是否帮助您的IDE或交互式解释器(REPL)做更好的自动完成取决于IDE或解释器,可能是它的设置,即使对于Python≥3.5也是如此
对于Python 2,alternative notation using comments可用,支持PEP 0484的工具可能会或可能不会尊重。
让我们看一下基于注释的提示(Python 3.x)如何查找代码。 (基于注释,Python-2.x兼容的提示留给读者练习。)
为了表示迭代MyList
个实例会产生MyClass
个对象,我们通过附加__iter__()
(由减号和更大值组成的箭头)提示返回类型->
-than sign)在函数定义的冒号后面,后跟返回值的类型。 __iter__()
本身不返回MyClass
,它返回一个迭代器。为了表明它应该是MyClass
以上的迭代器,我们使用generic [2] 中的Iterator
abstract base class typing
module:
from typing import Iterator
class MyClass:
# ...
class MyList:
# ...
def __iter__(self): -> Iterator[MyClass]
return iter(self.list)
为了能够履行此承诺,self.list
必须仅包含MyClass
个实例。因此,请通过类型提示__init__()
参数,让我们的调用者提供这样的信息:
from typing import Iterator, Iterable
# ...
class MyList:
def __init__(self, list: Iterable[MyClass]):
self.list = list
def __iter__(self): -> Iterator[MyClass]
return iter(self.list)
请注意,我选择了Iterable
通用抽象基类,而不是更具体的List
generic abstract base class(也不是Mapping
,Sequence
或AbstractSet
),您的实施仅依赖于iter(...)
。
[1] 除了过度使用时的可读性。所以as Mark writes,“如果您使用它们,请”负责任地使用类型提示“。
Python中包含的 [2] ≥3.5。对于较低版本,请使用backport可安装pip install typing
。
答案 2 :(得分:1)