迭代一个类型而不实例化它
Iterate over a type without instantiating it
问题
我希望能够在不实例化类型的情况下迭代它,类似于枚举。
class Foo:
"""Class I want to iterate over without instantiating."""
ALLOWED_VALUES = (1, 2, 3)
# I want iterating over `Foo` to be equivalent to iterating over `Foo.ALLOWED_VALUES`
for val_from_tuple, val_from_foo in zip(Foo.ALLOWED_VALUES, Foo):
assert val_from_tuple == val_from_foo
此行为对于枚举是可能的,但前提是 ALLOWED_VALUES
是有效的 python 名称。我希望在没有此限制的情况下具有相同的迭代行为。
我试过的
我尝试将 __iter__()
作为 Foo
上的 staticmethod
实现,这样就不需要 Foo
的实例来获得 Iterator
它。这允许我迭代 Foo.__iter__()
,但 iter(Foo)
会引发错误。这似乎是因为 iter(Foo)
在 type
上查找 __iter__
方法,而不是在 Foo
上查找(因为 Foo
是一个 type
对象)。
class Foo:
"""Class I want to iterate over without instantiating."""
ALLOWED_VALUES = (1, 2, 3)
@staticmethod
def __iter__():
return Foo.ALLOWED_VALUES
# This works, but isn't what I want because it involves calling `__iter__()` explicitly.
for val in Foo.__iter__():
print(val)
# This raises an error:
# `TypeError: 'type' object is not iterable`
for val in Foo:
print(val)
Enum
是可迭代的,因为它使用不同的元类(EnumMeta
而不是 type
)来创建它。您可以定义自己的元类来提供 __iter__
的定义,而 type
本身没有。
class IterableClass(type):
def __iter__(self):
yield from self.ALLOWED_VALUES
class Foo(metaclass=IterableClass):
ALLOWED_VALUES = (1,2,3)
for x, y in zip(Foo.ALLOWED_VALUES, Foo):
assert x == y
问题
我希望能够在不实例化类型的情况下迭代它,类似于枚举。
class Foo:
"""Class I want to iterate over without instantiating."""
ALLOWED_VALUES = (1, 2, 3)
# I want iterating over `Foo` to be equivalent to iterating over `Foo.ALLOWED_VALUES`
for val_from_tuple, val_from_foo in zip(Foo.ALLOWED_VALUES, Foo):
assert val_from_tuple == val_from_foo
此行为对于枚举是可能的,但前提是 ALLOWED_VALUES
是有效的 python 名称。我希望在没有此限制的情况下具有相同的迭代行为。
我试过的
我尝试将 __iter__()
作为 Foo
上的 staticmethod
实现,这样就不需要 Foo
的实例来获得 Iterator
它。这允许我迭代 Foo.__iter__()
,但 iter(Foo)
会引发错误。这似乎是因为 iter(Foo)
在 type
上查找 __iter__
方法,而不是在 Foo
上查找(因为 Foo
是一个 type
对象)。
class Foo:
"""Class I want to iterate over without instantiating."""
ALLOWED_VALUES = (1, 2, 3)
@staticmethod
def __iter__():
return Foo.ALLOWED_VALUES
# This works, but isn't what I want because it involves calling `__iter__()` explicitly.
for val in Foo.__iter__():
print(val)
# This raises an error:
# `TypeError: 'type' object is not iterable`
for val in Foo:
print(val)
Enum
是可迭代的,因为它使用不同的元类(EnumMeta
而不是 type
)来创建它。您可以定义自己的元类来提供 __iter__
的定义,而 type
本身没有。
class IterableClass(type):
def __iter__(self):
yield from self.ALLOWED_VALUES
class Foo(metaclass=IterableClass):
ALLOWED_VALUES = (1,2,3)
for x, y in zip(Foo.ALLOWED_VALUES, Foo):
assert x == y