如何为方法强制执行unicode参数?

时间:2009-11-04 16:51:46

标签: python unicode arguments decorator

我有一个带有getter和setter方法的模型类,以及偶尔的静态方法。我想强制使用unicode字符串作为特定方法的参数,并且使用装饰器是我的第一个想法。现在我有这样的事情:

import types

class require_unicode(object):

    def __init__(self, function):
        self.f = function

    def __call__(self, string):
        if not isinstance(string, types.UnicodeType):
            raise ValueError('String is not unicode')
        return self.f(string)

class Foo(object):

    something = 'bar'

    @staticmethod
    @require_unicode
    def do_another(self, string):
        return ' '.join(['baz', string])

    @require_unicode
    def set_something(self, string):
        self.something = string

foo = Foo()
foo.set_something('ValueError is raised')
foo.set_something(u'argument count error')
foo.do_another('ValueError is raised')
foo.do_another(u'argument count error')

在上面的代码中,decorator __call__内部的方法调用因错误的参数计数而失败(因为'foo'对象引用丢失了?)。在做一些愚蠢的事情之前我想问你们。应该怎么做?

3 个答案:

答案 0 :(得分:1)

我认为,问题出在@staticmethod装饰器上,而不是你的require_unicode装饰器。与classmethods不同,Staticmethods不接受对类的引用作为第一个参数,因此您的参数签名是错误的。

您必须将do_another更改为@classmethod,或从参数中删除self

编辑:并且,请注意, - @ classmethod-decorated方法接收作为第一个参数,而实例方法接收对类实例的引用 (自)。因此,最好将第一个参数命名为classmethod“cls”或其他东西,而不是“self”,这样就不会让任何人感到困惑。

答案 1 :(得分:0)

我认为这是unpythonic - 你永远不应该检查你的参数的类型,而是检查它们是否具有必要的方法和属性。最简单的方法是假设它们在那里然后获得异常,但我想你也可以做getattr。只是检查事物的类型。

答案 2 :(得分:0)

另一种选择是使用断言。这取决于是否将非unicode类型传递给您的方法应该被视为编程错误,这在开发过程中应该是明显的。

import types
class Foo:
    def set_something(self, string):
        assert isinstance(string, types.UnicodeType), 'String is not unicode'
        self.something = string

只要AssertionError不是unicode类型,这将引发string异常,但仅当Python解释器以“deubg”模式运行时才会引发-O异常。如果使用{{1}}选项运行Python,则解释器会有效地忽略断言。