如何在 class 中实现理解
How to implement comprehension in a class
据我所知,Python 中的解析式仅适用于列表、字典、元组和集合。 Python data model.
中没有关于理解的内容
元组的语法很有趣
>>> tuple(i for i in range(3))
(0, 1, 2)
按照同样的模式,我想为我的习惯写一个理解class。
>>> MySequence(i for i in range(3))
MySequence(0, 1, 2)
>>> MyMapping{str(i): i for i in range(3)}
MyMapping({'0': 0, '1': 1, '2': 2})
我怎样才能做到这一点?
我通过子类化和扩展 __init__ 方法设法实现了这一点。遇到AbsList
,它继承自list
,初始化时取每个数的绝对值
class AbsList(list):
def __init__(self, li):
super().__init__(abs(l) for l in li)
def __repr__(self):
return f"{self.__class__.__name__}({super().__repr__()})"
>>> AbsList(-i for i in range(-3))
AbsList([0, 1, 2])
AbsDict
很像。
class AbsDict(dict):
def __init__(self, di):
super().__init__({key: abs(value) for key, value in di.items()})
def __repr__(self):
return f"{self.__class__.__name__}({super().__repr__()})"
>>> AbsDict({str(i): -i for i in range(3)})
AbsDict({'0': 0, '1': 1, '2': 2})
我想删除 () 括号,但我做不到。
您混淆了两个不相关的东西:class 实例化和(生成器-)理解。
tuple(i for i in range(3))
相当于
tuple((i for i in range(3)))
相当于
generator = (i for i in range(3))
tuple(generator)
generator-comprehension 在 在 tuple.__init__
(或 __new__
)被调用之前计算。通常,Python 中的所有参数在传递给可调用对象之前都会进行评估。
任何 class 都可以接受一个可迭代对象(例如生成器)进行实例化,如果你相应地编码 __init__
,例如
class AcceptIterable:
def __init__(self, it):
for x in it:
print(x)
演示:
>>> a = AcceptIterable(i for i in range(3))
0
1
2
>>> a = AcceptIterable([i for i in range(3)])
0
1
2
>>> a = AcceptIterable(range(3))
0
1
2
>>> a = AcceptIterable([0, 1, 2])
0
1
2
据我所知,Python 中的解析式仅适用于列表、字典、元组和集合。 Python data model.
中没有关于理解的内容元组的语法很有趣
>>> tuple(i for i in range(3))
(0, 1, 2)
按照同样的模式,我想为我的习惯写一个理解class。
>>> MySequence(i for i in range(3))
MySequence(0, 1, 2)
>>> MyMapping{str(i): i for i in range(3)}
MyMapping({'0': 0, '1': 1, '2': 2})
我怎样才能做到这一点?
我通过子类化和扩展 __init__ 方法设法实现了这一点。遇到AbsList
,它继承自list
,初始化时取每个数的绝对值
class AbsList(list):
def __init__(self, li):
super().__init__(abs(l) for l in li)
def __repr__(self):
return f"{self.__class__.__name__}({super().__repr__()})"
>>> AbsList(-i for i in range(-3))
AbsList([0, 1, 2])
AbsDict
很像。
class AbsDict(dict):
def __init__(self, di):
super().__init__({key: abs(value) for key, value in di.items()})
def __repr__(self):
return f"{self.__class__.__name__}({super().__repr__()})"
>>> AbsDict({str(i): -i for i in range(3)})
AbsDict({'0': 0, '1': 1, '2': 2})
我想删除 () 括号,但我做不到。
您混淆了两个不相关的东西:class 实例化和(生成器-)理解。
tuple(i for i in range(3))
相当于
tuple((i for i in range(3)))
相当于
generator = (i for i in range(3))
tuple(generator)
generator-comprehension 在 在 tuple.__init__
(或 __new__
)被调用之前计算。通常,Python 中的所有参数在传递给可调用对象之前都会进行评估。
任何 class 都可以接受一个可迭代对象(例如生成器)进行实例化,如果你相应地编码 __init__
,例如
class AcceptIterable:
def __init__(self, it):
for x in it:
print(x)
演示:
>>> a = AcceptIterable(i for i in range(3))
0
1
2
>>> a = AcceptIterable([i for i in range(3)])
0
1
2
>>> a = AcceptIterable(range(3))
0
1
2
>>> a = AcceptIterable([0, 1, 2])
0
1
2