python meta class 装饰器
研究了一下RobotFramework_Selenium2Library 中的 KeywordGroup.py 这个模块
发现里面的方法写的挺好的,自己一步一步的打印去了解了一下。
对理解 meta class 和 装饰器很有帮助,这里给大家分享一下例子
MyKeyword class 是自己写的一个测试类,用来测试Meta class 和装饰器
这一部分代码搞懂之后,你对meta class 和 装饰器会有一个新的概念
把代码随便复制到一个python 文件中,试着运行一下,或者按照你自己的想法,修改里面的参数和方法
#coding:utf-8
import sys
import inspect
try:
from decorator import decorator
except SyntaxError: # decorator module requires Python/Jython 2.4+
decorator = None
if sys.platform == 'cli':
decorator = None # decorator module doesn't work with IronPython 2.6
def _run_on_failure_decorator(method, *args, **kwargs): #装饰器方法
self = args[0] #这里很重要,这个参数你打印出来会发现他是一个类对象,然后我们就可以通过这个对象调用类中的属性和方法
print "*****1****",method #打印装饰器参数
print "*****2****",args[0] #同上
print "*****3*****",args[1] #同上
already_in_keyword = getattr(self, "_already_in_keyword", False) # If False, we are in the outermost keyword (or in `run_keyword`, if it's a dynamic library)
print "*****4*****",already_in_keyword
self._already_in_keyword = True # Set a flag on the instance so that as we call keywords inside this call and this gets run again, we know we're at least one level in.
try:
return method(*args, **kwargs)
except Exception, err:
print "功能错误"
if hasattr(self, '_run_on_failure') and not self._has_run_on_failure:
# If we're in an inner keyword, track the fact that we've already run on failure once
self._has_run_on_failure = True
self._run_on_failure()
raise
finally:
if not already_in_keyword:
# If we are in the outer call, reset the flags.
self._already_in_keyword = False
self._has_run_on_failure = False
class KeywordGroupMetaClass(type): #定义元类
def __new__(cls, clsname, bases, dict):
if decorator:
for name, method in dict.items():
print name,method
if not name.startswith('_') and inspect.isroutine(method):
dict[name] = decorator(_run_on_failure_decorator, method) #给类方法绑定装饰器
return type.__new__(cls, clsname, bases, dict)
class KeywordGroup(object):
__metaclass__ = KeywordGroupMetaClass #指定继承的元类
class MyKeyword(KeywordGroup): #继承 KeywordGroup, 也就意味着MyKeyword 也继承 KeywordGroupMetaClass 的属性
"""test run on failure"""
def __init__(self):
self._run_on_failure_keyword = None
self._running_on_failure_routine = False
self._already_in_keyword = True
self._has_run_on_failure = False
def testF(self,arg1):
self._run_on_failure_keyword=True
print arg1
print 1/0
def _run_on_failure(self):
print "失败后运行的"
t = MyKeyword() #生成测试实例对象
t.testF("测试传参") #调用测试方法