python meta class 裝飾器

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

發佈了80 篇原創文章 · 獲贊 38 · 訪問量 29萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章