[英]Get decorated class from its name in the decorator?
我用@bot_thinking
裝飾了一些方法,該functions
將有關裝飾方法的一些信息存儲在functions
屬性中。 其中一條信息是“ class_name”,但是我的程序需要將類類型作為變量,例如RandomBot
。 我想上這堂課。
這是一些示例代碼:
class DepthPrunedMinimaxAgent(Agent):
@bot_thinking(associated_name="minimax profondeur")
def select_move(self, game_state: GameState):
上面是代碼的修飾部分。
裝飾器:
functions = {}
def bot_thinking(associated_name, active=True):
def _(func):
if active:
class_name = func.__qualname__.rsplit('.')[-2]
import sys
# class_name_2=getattr(sys.modules[__name__], class_name)
# module=importlib.import_module('sources.agent')
functions[associated_name] = (associated_name, class_name,
globals()[class_name], func)
else:
functions.pop(associated_name)
return _
bot_thinking
不是真正的裝飾器,而是裝飾器工廠。 從func
函數中,我得到了class_name
,但是我無法使用@ m.kocikowski 接受的答案來找到正確的類,因為此類已被修飾,因此它已經導入了注釋模塊,因此從的模塊中導入帶注釋的模塊的注釋將導致循環導入,而python似乎不允許這樣做。
您是否看到一種從類名獲取類的方法?
ps:ps:更清楚:代碼的注釋部分需要導入到帶注釋的類(以從其名稱中檢索類),這也需要導入注釋(以使注釋起作用)。
問題是當bot_thinking()
裝飾器工廠(和裝飾器本身)正在執行時,尚未定義該類。 我能想到的唯一解決方法是在定義類后修補問題,如下所示:
from pprint import pprint, pformat
functions = {}
def bot_thinking(associated_name, active=True):
def _(func):
if active:
class_name = func.__qualname__.split(".")[-2]
functions[associated_name] = (associated_name, class_name, class_name, func)
else:
functions.pop(associated_name, None)
return func # Decorators must return a callable.
return _
class Agent: pass
class GameState: pass
class DepthPrunedMinimaxAgent(Agent):
@bot_thinking(associated_name="minimax profondeur")
def select_move(self, game_state: GameState):
pass
# After class is defined, update data put into functions dictionary.
for associated_name, info in functions.items():
functions[associated_name] = (info[0], info[1], globals()[info[2]], info[3])
pprint(functions)
輸出:
{'minimax profondeur': ('minimax profondeur',
'DepthPrunedMinimaxAgent',
<class '__main__.DepthPrunedMinimaxAgent'>,
<function DepthPrunedMinimaxAgent.select_move at 0x00F158A0>)}
如果使用描述符類而不是函數作為裝飾器,則可以執行所需的操作,至少在使用Python 3.6或更高版本的情況下。 這是因為在描述符協議中添加了一個新方法__set_name__
。 當描述符對象另存為類變量時,它將被調用。 盡管大多數描述符將使用它來記錄將其另存為的名稱,但是您可以使用它來獲取您所在的類。
您確實需要使裝飾器對象包裝真實的函數(實現調用和描述符查找方法),而不是能夠返回您正在裝飾的未修改函數。 這是我嘗試快速而骯臟的實現。 我不太了解您在使用functions
做什么,因此我可能沒有在其中放入正確的數據,但是它應該足夠接近才能理解這個想法( owner
是存儲方法的類)。
functions = {}
def bot_thinking(associated_name, active=True):
class decorator:
def __init__(self, func):
self.func = func
def __set_name__(self, owner, name):
if active:
functions[associated_name] = (associated_name, owner.__name__,
owner, self.func)
else:
functions.pop(associated_name)
def __get__(self, obj, owner):
return self.func.__get__(obj, owner)
def __call__(self, *args, **kwargs):
return self.func(*args, **kwargs)
return decorator
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.