自定义占位符,如python中的None

时间:2011-05-31 09:21:54

标签: python metaclass

我在一个以另一个函数或方法作为参数的函数中使用argspec,并返回一个这样的元组:

(("arg1", obj1), ("arg2", obj2), ...)

这意味着传递函数的第一个参数是arg1,它的默认值为obj1,依此类推。

这是擦除:如果它没有默认值,我需要一个占位符值来表示这一点。我不能使用None,因为我无法区分没有默认值默认值是None 。对于False,0,-1等也是如此。我可以使它成为一个单元素的元组,但是检查它的代码会很难看,我不能轻易把它变成一个字典。所以我想我会创建一个非类似的非对象,这就是我想出的:

class MetaNoDefault(type):
    def __repr__(cls):
        return cls.__name__
    __str__ = __repr__

class NoDefault(object):
    __metaclass__ = MetaNoDefault

现在("arg1", NoDefault)表示arg1没有默认值,我可以执行if obj1 is NoDefault:等操作。元类使其打印为NoDefault而不是<class '__main__.NoDefault'>。< / p>

有没有理由不这样做?有更好的解决方案吗?

3 个答案:

答案 0 :(得分:5)

我最喜欢的哨兵是Ellipsis,如果我quote我自己:

  

它就在那里,它是一个对象,它是一个单例,它的名字意味着“缺乏”,并且它不是过度使用的无(可以作为正常数据流的一部分放入队列中)。 YMMV。

答案 1 :(得分:4)

前段时间我的情况类似。这就是我想出来的。

# Works like None, but is also a no-op callable and empty iterable.
class NULLType(type):
    def __new__(cls, name, bases, dct):
        return type.__new__(cls, name, bases, dct)
    def __init__(cls, name, bases, dct):
        super(NULLType, cls).__init__(name, bases, dct)
    def __str__(self):
        return ""
    def __repr__(self):
        return "NULL"
    def __nonzero__(self):
        return False
    def __len__(self):
        return 0
    def __call__(self, *args, **kwargs):
        return None
    def __contains__(self, item):
        return False
    def __iter__(self):
        return self
    def next(*args):
        raise StopIteration
NULL = NULLType("NULL", (type,), {})

它也可以作为null callable和sequence。

答案 2 :(得分:3)

没有任何理由不为此目的使用此类哨兵物品。作为类对象的替代方法,您还可以创建动态创建类型的单例实例:

NoDefault = type('NoDefault', (object,), {
    '__str__': lambda s: 'NoDefault', '__repr__': lambda s: 'NoDefault'})()