用于执行参数类型的装饰器 [英] Decorator for Enforcing Argument Types

查看:59
本文介绍了用于执行参数类型的装饰器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不确定之前是否已经这样做了,但是我以前在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆