0
# addmember.py

def addmember(memberlist, newmembers):
    if type(newmembers) not in (type([]), type(())):
        newmembers = [newmembers]
    for m in newmembers:
        if m not in memberlist:
            memberlist.append(m)
    return memberlist

我先制作上面的python文件,然后在IDLE加载它

 >>> members = ['a', 'b']
 >>> import addmember
 >>> addmember.addmember(members, 'c')

然后,错误警报如下:

如果 type(newmembers) 不在 (type([]), type(())) 中:
TypeError: type() 需要 1 或 3 个参数

我无法理解错误的含义。

提前谢谢~~ :)

4

3 回答 3

6

看起来你想要

if not isinstance(newmembers, (list, tuple)):

isinstance()

type()比较通常是检查对象兼容性的不好方法,因为它们忽略了继承。例如:

>>> from collections import defaultdict
>>> d = defaultdict()
>>> type(d) == dict
False
>>> isinstance(d, dict)
True
于 2013-07-09T02:48:31.310 回答
3

解决此问题的最佳方法是根本不检查类型。

你想在这里检查的唯一原因是,如果你没有得到一个列表或元组或其他你可以迭代的东西,你可以迭代一个值,对吧?那么为什么不试着把它当作一个可迭代的,如果你不能就回退呢?

def addmember(memberlist, newmembers):
    try:
        iterator = iter(newmembers)
    except TypeError:
        iterator = [newmembers]
    for m in iterator:
        if m not in memberlist:
            memberlist.append(m)
    return memberlist

如果你做了很多这样的事情,你可以把它包装在一个函数中:

def iterscalar(iterable_or_scalar):
    try:
        return iter(iterable_or_scalar)
    except TypeError:
        return [iterable_or_scalar]

现在你只需这样做:

def addmember(memberlist, newmembers):
    for m in iterscalar(newmembers):
        if m not in memberlist:
            memberlist.append(m)
    return memberlist

有时您希望将字符串视为标量,即使它们实际上是可迭代的。为此,您确实需要某种检查。

但最好检查“是可迭代的,不是字符串”而不是“是列表或元组”,因为非字符串可迭代的类型比字符串多得多。

如果你想要比字符串检查更通用的东西,你通常想要检查它next(iter(newmembers))newmembers.

当然,您真正想要什么取决于您的用例。


当然,如果您只是使用了正确的数据类型,则根本不需要此代码。例如,如果memberlist是 aset而不是 a list,您可以只调用memberlist.update(),它会添加任何不存在的成员并忽略那些存在的成员。(如果您需要保留它们被发现的顺序,请使用文档OrderedSet中的简单配方collections。)除了简单得多之外,它也会快得多(因为您不需要继续搜索每个新成员的不断增长的列表)。

于 2013-07-09T03:02:57.930 回答
2

不要type()用来检查对象是什么类型。使用isinstance()

if not isinstance(newmembers, (list, tuple)):
    dostuff()

您的代码不应重现该错误,您只需将一个参数传递给 type()

于 2013-07-09T02:48:17.140 回答