簡體   English   中英

修改類中多個方法的調用參數

[英]Modifying call arguments of multiple methods in class

我有一堂課,有太多的方法。 大多數方法都帶有一個參數(總是相同的名稱)-我需要將參數的類型更改為其他名稱,但也要接受參數的“舊”版本(並raise DeprecationWarning )。

編輯我們可以假設參數始終作為關鍵字參數傳遞。

干的方法是什么?

我想到的第一個解決方案是:

def check_orc(orc):
    if isinstance(Snaga, orc):
        orc = convert_to_urukhai(orc)
        raise DeprecationWarning("You should not be sending snaga to combat")
    return orc

class Warrior():
    def slash_orc(sword, shield, opponent):
       opponent = check_orc(opponent)
       ...

    def hack_orc(warhammer, opponent):
       opponent = check_orc(opponent)
       ...

avasal的評論是正確的。 但是,出於教育目的,這是您想要的裝飾器實現:

from functools import wraps

def convert_orc(f):
    @wraps(f)
    def wrapper(self, opponent, *args, **kwargs):
        if isinstance(Snaga, orc):
            raise DeprecationWarning(...)
            return f(self, convert_to_urukhai(opponent), *args, **kwargs)
        else:
            return f(self, opponent, *args, **kwargs)
    return wrapper

class Warrior():
    @convert_orc
    def slash_orc(self, opponent, sword, shield):
       ...

    @convert_orc
    def hack_orc(self, opponent, warhammer):
       ...

注意:我已將opponent移至參數中的第一個位置

您能否確定這是否始終是最后一個參數? 如果沒有,則必須使用其名稱。

我的想法是這樣做:

def check_orc(orc):
    if isinstance(orc, int):
        orc = str(orc)
        print DeprecationWarning("You should not be sending snaga to combat")
    return orc

def check_opp(meth):
    code = meth.func_code
    argnames = code.co_varnames[:code.co_argcount]
    if 'opponent' in argnames:
        from functools import wraps
        argidx = argnames.index('opponent')
        @wraps(meth)
        def replace(*a, **k):
            if 'opponent' in k:
                k['opponent'] = check_orc(k['opponent'])
            else:
                a = list(a)
                a[argidx] = check_orc(a[argidx])
                a = tuple(a)
            return meth(*a, **k)
        return replace
    else:
        return meth

class Warrior():
    @check_opp
    def slash_orc(self, sword, shield, opponent):
       print "slash", (sword, shield, opponent)

    @check_opp
    def hack_orc(self, warhammer, opponent):
       print "hack", (warhammer, opponent)

Warrior().slash_orc(1,3,4)
Warrior().hack_orc(6,5)
Warrior().slash_orc(1,3,opponent=4)
Warrior().hack_orc(6,opponent=5)
Warrior().slash_orc(1,3,"4")
Warrior().hack_orc(6,"5")
Warrior().slash_orc(1,3,opponent="4")
Warrior().hack_orc(6,opponent="5")

這是一個很丑陋的技巧,但是仍然可以正常工作,並且可以避免重新排列參數。

在這里,我使用一種檢查來找到正確的參數並對其進行修改,而不管它是否已作為關鍵字或索引參數傳遞。

請注意,為了使它對我有用,我對測試進行了一些更改(我“棄用” int並需要strs)。 您只需要我的check_opp()函數並將其應用於所需的任何地方。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM