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("測試傳參") #調用測試方法