用于执行参数类型的装饰器 [英] Decorator for Enforcing Argument Types
问题描述
我不确定之前是否已经这样做了,但是我以前在Google上的工作都不容易找到
,所以这里我提出了一个简单的装饰器
记录并验证函数参数的类型。
欢迎提供反馈/建议/批评。
'''''' >
2006.12.21已创建。
'''''
导入unittest
import inspect
def arguments(* args):
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
用法:
@arguments(type1,type2,[type3.1,type3.2,...,type3.N] ,
type4,...,typeN)
def somefunc(arg1,arg2,arg3,arg4,...,argN):
做的东西
返回
''''''
返回lambda f:_Arguments(f,* args)
class _Arguments(object):
#todo:extend来验证Zope inte rfaces
def __init __(self,fn,* args):
self.fn = fn
#create参数类型列表
self.arguments = []
arg中arg的
:
如果不是isinstance(arg,list):
arg = list([arg])
arg = set(arg)
self.arguments.append(arg)
#创建名称到索引查找
argNames,varArgName,varkwName,defaults =
inspect.getargspec(fn)
断言len (argNames)== len(self.arguments),''参数列表
类型必须与参数数量匹配''
self.argNameToIndex = {}
for i,name in enumerate(argNames):
self.argNameToIndex [name] = i
if defaults and i> = len(self .arguments)-len(默认值):
#将默认类型添加到允许的类型
self.arguments [i] .add(type(defaults [i - (len(self.arguments)-len(默认))]))
def验证(self,value,i):
''' '''回覆如果值与允许的类型匹配,则转为true。对于第i个参数,
。''''''
如果不是isinstance(i,int):
如果我不在self.argNameToIndex:
引发异常,''未知参数名称:%s''%i
i = self.argNameToIndex [i]
返回self.arguments中的类型(值)[i]
def verifyAll(self,* values,** kvalues):
''''''如果所有值匹配允许的类型
作为相应的参数,则返回true。'''''''
表示i,枚举值(值):
如果不是self.verify(value,i):
返回False
为名称,值为kvalues.iteritems( ):
如果不是self.verify(值,名称):
返回False
返回True
def __call __(self,* args,** kargs):
断言self.verifyAll(* args,** kargs),''参数类型必须是
以%s''%self.arguments
ret的形式出现urn self.fn(* args,** kars)
class Test(unittest.TestCase):
def test(self):
@arguments(str,[int,float],list)
def foo(abc,xyz,big = None):
返回''%s%s''%(abc,xyz)
self.assertEqual(type(foo),_ Arguments)
self .assertEqual(len(foo.arguments),3)
self.assertEqual(foo.arguments [2],set([list,type(None)]))
self.assertEqual(foo.verify(''how'',0),True)
self.assertEqual(foo.verify(123,0),False)
self.assertEqual(foo.verify(123,1),True)
self.assertEqual(foo.verify(1.23,1),True)
self.assertEqual (foo.verifyAll(''how'',123),True)
self.assertEqual(foo.verifyAll(123,''how''),False)
self.assertEqual(foo.verifyAll(abc =''how'',xyz = 123),True)
self.assertEqual(foo.verifyAll(''how'',xyz = 123) ,是的)
self.assertEqual(foo.verifyAll( 'how'',xyz =''oeuuo''),False)
self.assertEqual(foo.verifyAll(''how'',xyz = 123,big = N one),True)
self.assertEqual(foo.verifyAll(''how'',xyz = 123,big = [1,2,3]),
True)
self.assertEqual(foo.verifyAll(''how'',123,[1,2,3]),True)
self.assertEqual(foo.verifyAll('''怎么'',123,''asoenhua s''),False)
self.assertTrue(foo(''how'',123))
self.assertTrue (foo(abc =''how'',xyz = 123,big = None))
if __name__ ==''__ main__'':
unittest.main()
I''m not sure if this has been done before, but I couldn''t easily find
any prior work on Google, so here I present a simple decorator for
documenting and verifying the type of function arguments.
Feedback/suggestions/criticism is welcome.
''''''
2006.12.21 Created.
''''''
import unittest
import inspect
def arguments(*args):
''''''A simple decorator for formally documenting
and verifying argument types.
usage:
@arguments(type1, type2, [type3.1, type3.2, ..., type3.N],
type4, ..., typeN)
def somefunc(arg1, arg2, arg3, arg4, ..., argN):
do stuff
return
''''''
return lambda f:_Arguments(f, *args)
class _Arguments(object):
# todo: extend to verify Zope interfaces
def __init__(self, fn, *args):
self.fn = fn
# create argument type list
self.arguments = []
for arg in args:
if not isinstance(arg, list):
arg = list([arg])
arg = set(arg)
self.arguments.append(arg)
# create name-to-index lookup
argNames, varArgName, varkwName, defaults =
inspect.getargspec(fn)
assert len(argNames) == len(self.arguments), ''list of argument
types must match the number of arguments''
self.argNameToIndex = {}
for i,name in enumerate(argNames):
self.argNameToIndex[name] = i
if defaults and i >= len(self.arguments)-len(defaults):
# add default type to allowable types
self.arguments[i].add(type(defaults[i-(len(self.arguments)-len(defaults))]))
def verify(self, value, i):
''''''Returns true if the value matches the allowable types
for the ith argument.''''''
if not isinstance(i, int):
if i not in self.argNameToIndex:
raise Exception, ''unknown argument name: %s'' % i
i = self.argNameToIndex[i]
return type(value) in self.arguments[i]
def verifyAll(self, *values, **kvalues):
''''''Returns true if all values matche the allowable types
for their corresponding arguments.''''''
for i,value in enumerate(values):
if not self.verify(value, i):
return False
for name,value in kvalues.iteritems():
if not self.verify(value, name):
return False
return True
def __call__(self, *args, **kargs):
assert self.verifyAll(*args, **kargs), ''argument types must be
in the form of %s'' % self.arguments
return self.fn(*args, **kargs)
class Test(unittest.TestCase):
def test(self):
@arguments(str, [int, float], list)
def foo(abc, xyz, big=None):
return ''%s %s'' % (abc, xyz)
self.assertEqual(type(foo), _Arguments)
self.assertEqual(len(foo.arguments), 3)
self.assertEqual(foo.arguments[2], set([list, type(None)]))
self.assertEqual(foo.verify(''how'', 0), True)
self.assertEqual(foo.verify(123, 0), False)
self.assertEqual(foo.verify(123, 1), True)
self.assertEqual(foo.verify(1.23, 1), True)
self.assertEqual(foo.verifyAll(''how'',123), True)
self.assertEqual(foo.verifyAll(123,''how''), False)
self.assertEqual(foo.verifyAll(abc=''how'',xyz=123), True)
self.assertEqual(foo.verifyAll(''how'',xyz=123), True)
self.assertEqual(foo.verifyAll(''how'',xyz=''oeuuo''), False)
self.assertEqual(foo.verifyAll(''how'',xyz=123,big=N one), True)
self.assertEqual(foo.verifyAll(''how'',xyz=123,big=[1,2,3]),
True)
self.assertEqual(foo.verifyAll(''how'',123,[1,2,3]), True)
self.assertEqual(foo.verifyAll(''how'',123,''asoenhua s''), False)
self.assertTrue(foo(''how'',123))
self.assertTrue(foo(abc=''how'',xyz=123,big=None))
if __name__ == ''__main__'':
unittest.main()
推荐答案
" Chris" < ch ******* @ gmail.com写信息
新闻:11 ********************** @ 79g2000cws.googlegro ups.com ...
"Chris" <ch*******@gmail.comwrote in message
news:11**********************@79g2000cws.googlegro ups.com...
我不确定之前是否已经完成,但我不能轻易找到
之前在谷歌工作的所有工作,所以在这里我提供了一个简单的装饰,用于
记录和验证函数参数的类型。
欢迎提出反馈/建议/批评。
I''m not sure if this has been done before, but I couldn''t easily find
any prior work on Google, so here I present a simple decorator for
documenting and verifying the type of function arguments.
Feedback/suggestions/criticism is welcome.
他们的Python wiki有一个装饰创意/提交的页面,比较你的
到这个:
http://wiki.python.org/moin/PythonDe...348f78db34303e
- Paul
They Python wiki has a page for decorator ideas/submissions, compare yours
to this one:
http://wiki.python.org/moin/PythonDe...348f78db34303e
-- Paul
12月21日下午3:57,Paul McGuire < p ... @ austin.rr._bogus_.comwrote:
On Dec 21, 3:57 pm, "Paul McGuire" <p...@austin.rr._bogus_.comwrote:
" Chris" < chriss ... @ gmail.comwrote in messagenews:11 ********************** @ 79g2000cws.go oglegroups.com ...
"Chris" <chriss...@gmail.comwrote in messagenews:11**********************@79g2000cws.go oglegroups.com...
我不确定以前是否已经这样做了,但是我以前在谷歌上工作都不容易找到
所以这里我提供一个简单的装饰器
记录和验证函数参数的类型。
反馈/建议/批评是受欢迎的。他们的Python维基有一个装饰创意/提交的页面,比较你的
I''m not sure if this has been done before, but I couldn''t easily find
any prior work on Google, so here I present a simple decorator for
documenting and verifying the type of function arguments.
Feedback/suggestions/criticism is welcome.They Python wiki has a page for decorator ideas/submissions, compare yours
到这一个: http://wiki.python.org/moin/PythonDe...-308f2b3507ca9 ...
to this one:http://wiki.python.org/moin/PythonDe...-308f2b3507ca9...
谢谢,我没有意识到那个页面。我设计了我允许
内省,所以程序可以明确地看到什么类型的
函数需要并测试参数组合,如果需要的话,
例子似乎不允许。我的每个
参数也支持多种类型。但是,我喜欢那个也检查返回值的方式。
Chris
Thanks, I was unaware of that page. I designed mine allow for
introspection, so the program can explicitly "see" what types a
function takes and test argument combinations if need be, which that
example doesn''t seem to allow. Mine also supports multiple types per
argument. However, I like how that one also checks the return value.
Chris
Chris写道:
Chris wrote:
我不确定这是否在
之前完成
I''m not sure if this has been done before
参见原始规范中的示例4:
http:// www .python.org / dev / peps / pep-0318 /#examples
< / F>
see example 4 in the original specification:
http://www.python.org/dev/peps/pep-0318/#examples
</F>
这篇关于用于执行参数类型的装饰器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!