如何执行方法的unicode参数?
问题描述:
我有一个模型类与getter和setter方法,偶尔静态方法。我想强制使用unicode字符串作为具体方法的参数,使用装饰器是我的第一个想法。现在,我有这样的事情:如何执行方法的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')
在上面的代码里面装饰的__call__
失败的方法调用由于错误的参数个数(因为“富”对象裁判失踪?)。在做一些愚蠢的事情之前,我想问你们。这应该如何完成?
答
我认为,你的问题是用@staticmethod装饰器,而不是用你的require_unicode装饰器。与classmethods不同,静态方法不会将类引用作为第一个参数,所以您的参数签名是错误的。
您必须将do_another更改为@classmethod,或从参数中删除self
。
编辑:和,你要知道, - @类方法装饰方法得到的类作为第一个参数,而实例方法接收参照类(个体经营)实例。因此,将第一个参数命名为类方法“cls”或其他内容是一个好主意,而不是“自我”,因此不会混淆任何人。
答
我会认为这是unpythonic - 你不应该检查你的参数的类型,而是检查他们是否有必要的方法和属性。最简单的方法是假设他们在那里,否则会得到例外,但我想你也可以做getattr
。只需不要检查事物的类型。
答
另一种选择是使用断言。这取决于是否将非Unicode类型传入您的方法应视为编程错误,在开发过程中应该显而易见。
import types
class Foo:
def set_something(self, string):
assert isinstance(string, types.UnicodeType), 'String is not unicode'
self.something = string
这将引发AssertionError
例外,每当string
是unicode的类型不是,但只有当Python的interpretter在“deubg”模式下运行。如果你使用-O
选项运行Python,解析器会高效地忽略断言。
我知道这是unpythonic,但是当将编码字符串保存到数据库时,在这里防止编码字符串会在以后节省很多麻烦。 – tuomur 2009-11-04 19:00:26
@eclaird:一旦你绝对肯定*要求* unicode,只要调用'unicode()'就可以得到并称之为好的。 – Teddy 2009-11-05 18:17:07