我想要一个能够处理序列和单个元素参数的泛型函数get_me()
。
代码如下:
from typing import Sequence
class class_1:
def __init__(self, i: int=0):
self.name = 'A'+str(i)
def __repr__(self):
return self.name
class class_2:
def __init__(self, i: int=0):
self.name = 'B'+str(i)
def __repr__(self):
return self.name
def get_me(seq: Sequence):
for s in seq:
print(f"n1 is {s[0].name}, 2 is {s[1].name}")
这适用于以下所有组合:
one = class_1(1), class_2(1)
two = class_1(2), class_2(2)
three = class_1(3), class_2(3)
many = [one, two, three]
many = (one, two, three)
many = {one, two}
many = one, two
get_me(many)
但给出的CCD_ 2
get_me(一个(
有可能让这个代码在没有try: except
的情况下处理它吗?
也许这就是你想要的:
from typing import Sequence, Union, Tuple
# ...
def get_me(seq: Union[Sequence, Tuple]):
if isinstance(seq, tuple):
seq = (seq,)
for s in seq:
print(f"n1 is {s[0].name}, 2 is {s[1].name}")
这依赖于单个元素是元组,就像您的示例中一样,但print
语句也是如此,所以这似乎是合理的。如果您需要它来工作于任何类型,您可以将其替换为Any
,并检查它是否不是序列——但当然,您还必须修改print
语句,以及使用该参数的任何其他代码。
您注意到,当您将many
定义为:时,此解决方案不起作用
many = one, two
这是正确的,因为这也使得许多Tuple
。
为了支持这一点,你需要这样的东西:
def get_me(seq: Sequence):
if not isinstance(seq[0], tuple):
seq = (seq,)
for s in seq:
print(f"n1 is {s[0].name}, 2 is {s[1].name}")
然而,这并没有那么严格或明确。另一种方法是:
class SuperClass:
pass
class Class1(SuperClass):
# ...
class Class2(SuperClass):
# ...
# ...
def get_me(seq: Union[Sequence[SuperClass], SuperClass]):
if isinstance(seq, SuperClass):
seq = (seq,)
for s in seq:
print(f"n1 is {s[0].name}, 2 is {s[1].name}")
如果所有的显式类型都是必需的,那么这是我更喜欢的解决方案。
由于参数类型的各种可能排列,在保持代码简单的同时,似乎无法避免try: except
。
所以代码。。。
def get_me(seq: Sequence):
try:
for s in seq:
print(f"n1 is {s[0].name}, 2 is {s[1].name}")
except (TypeError, AttributeError):
print(f"n1 is {seq[0].name}, 2 is {seq[1].name}")
适用于我所有可能的情况:
one = class_1(1), class_2(1)
two = class_1(2), class_2(2)
three = class_1(3), class_2(3)
many = [one, two, three]
many = (one, two, three)
many = {one, two}
many = one, two
get_me(many)
get_me(one)
get_me(two)
get_me(three)