如何执行方法的unicode参数?

如何执行方法的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。只需不要检查事物的类型。

+0

我知道这是unpythonic,但是当将编码字符串保存到数据库时,在这里防止编码字符串会在以后节省很多麻烦。 – tuomur 2009-11-04 19:00:26

+0

@eclaird:一旦你绝对肯定*要求* unicode,只要调用'unicode()'就可以得到并称之为好的。 – Teddy 2009-11-05 18:17:07

另一种选择是使用断言。这取决于是否将非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,解析器会高效地忽略断言。

+0

当然,我也想到了这一点,但想法装饰者会更干净的方式来做到这一点。 – tuomur 2009-11-05 06:06:12

+0

那你真的看起来更清洁吗?国际海事组织的断言更为明显,因为检查在方法开始时就在那里,而不是隐藏在可能从其他地方导入的类中。使用'-O'运行python时,您还可以获得有效声明成为NOP的性能优势。 – mhawke 2009-11-05 07:54:36