gpt4 book ai didi

python - 从 Python List 继承后覆盖追加方法

转载 作者:太空狗 更新时间:2023-10-29 17:51:43 25 4
gpt4 key购买 nike

我想创建一个只能接受特定类型的列表。因此,我试图从 Python 中的列表继承,并像这样覆盖 append() 方法:

class TypedList(list):
def __init__(self, type):
self.type = type

def append(item)
if not isinstance(item, type):
raise TypeError, 'item is not of type %s' % type
self.append(item) #append the item to itself (the list)

这将导致无限循环,因为 append() 的主体会调用自身,但我不确定除了使用 self.append(item) 之外还能做什么。

我应该怎么做?

最佳答案

I want to create a list that can onlyaccept certain types. As such, I'mtrying to inherit from a list inPython

不是最好的方法! Python 列表有如此多的变异方法,您必须覆盖一堆(并且可能会忘记一些)。

相反,包装一个列表,继承自 collections.MutableSequence,并在 MutableSequence 所在的极少数“阻塞点”方法中添加检查code> 依赖于实现所有其他的。

import collections

class TypedList(collections.MutableSequence):

def __init__(self, oktypes, *args):
self.oktypes = oktypes
self.list = list()
self.extend(list(args))

def check(self, v):
if not isinstance(v, self.oktypes):
raise TypeError, v

def __len__(self): return len(self.list)

def __getitem__(self, i): return self.list[i]

def __delitem__(self, i): del self.list[i]

def __setitem__(self, i, v):
self.check(v)
self.list[i] = v

def insert(self, i, v):
self.check(v)
self.list.insert(i, v)

def __str__(self):
return str(self.list)

oktypes 参数通常是您想要允许的类型的元组,但是当然可以在那里传递单个类型(并且,通过使该类型成为抽象基类,ABC ,您可以轻松地以这种方式执行您选择的任何类型的类型检查——但是,这是一个不同的问题)。

下面是一些使用此类的示例代码:

x = TypedList((str, unicode), 'foo', 'bar')
x.append('zap')
print x
x.append(23)

输出是:

['foo', 'bar', 'zap']
Traceback (most recent call last):
File "tl.py", line 35, in <module>
x.append(23)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/_abcoll.py", line 556, in append
self.insert(len(self), value)
File "tl.py", line 25, in insert
self.check(v)
File "tl.py", line 12, in check
raise TypeError, v
TypeError: 23

请特别注意,我们没有覆盖append——但append在那里并且表现如预期。

回溯中揭示了那个魔法背后的 secret :_abcoll.py(collections 模块中抽象基类的实现模块),在第 556 行,通过调用我们的 insert实现追加——当然,我们已经正确地覆盖了它。

这个“模板方法设计模式”(对于所有类型的 OOP 来说绝对宝贵——在 youtube 上寻找我关于设计模式的演讲,你会发现原因;-),以及其他优点,给我们带来了“瓶颈” effect” 我之前提到过:通过在必须实现的极少数方法上添加一些检查,您可以获得这样的优势,即这些检查适用于所有其他相关方法(Python 中的可变序列有很多那些;-).

我们最终得到一个非常强大和经典的“幕后”设计模式也就不足为奇了,因为这个实现策略背后的整个思想都来自不朽的经典“设计模式”一书(其作者通常集体被称为四人帮”;-): 更喜欢对象组合而不是继承。继承(来自具体类)是一种非常严格的耦合机制,一旦尝试就会充满“陷阱”使用它来做任何事情,即使只是稍微超出其严格限制;组合非常灵活和有用,并且从适当的抽象类继承可以很好地完成这幅画。

Scott Meyers 的优秀“Effective C++”,item 33 ,更强烈地说:使非叶类抽象。由于“非叶”他的意思是“任何继承自的类”,等效的措辞是“从不继承具体类”。

当然,Scott 是在 C++ 上下文中编写的,但是 Paul Haahr为 Java 提供了完全相同的建议,措辞为不要子类化具体类——我通常支持 Python,尽管我更喜欢四人组的更温和的措辞,更喜欢 composition over (concrete class) inheritance(但我知道 Scott 和 Paul 经常为需要非常直接和措辞强烈的建议的读者写作,这些建议几乎被表述为“命令”而不是建议,而不是更温和的措辞他们可能很容易以方便的名义忽略;-)。

关于python - 从 Python List 继承后覆盖追加方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3487434/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com