本文介绍了用于保存有关类的元数据的修饰符的替代方案的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在编写一个GUI库,我想让程序员提供有关他们的程序的元信息,我可以使用这些信息来微调图形用户界面。为此,我计划使用函数修饰符,例如:
class App:
@Useraction(description='close the program', hotkey='ctrl+q')
def quit(self):
sys.exit()
问题是此信息需要绑定到相应的类。例如,如果程序是一个图像编辑器,它可能有一个Image
类,它提供一些更多的Useraction:
class Image:
@Useraction(description='invert the colors')
def invert_colors(self):
...
但是,由于非绑定方法的概念在python3中已被删除,因此似乎没有找到函数的定义类的方法。(我找到了this old answer,但在装饰器中不起作用。)
那么,既然看起来装饰师不打算工作了,那么最好的方法是什么呢?我希望避免出现这样的代码
class App:
def quit(self):
sys.exit()
Useraction(App.quit, description='close the program', hotkey='ctrl+q')
如果可能的话。
为完整起见,@Useraction
修饰符应如下所示:
class_metadata= defaultdict(dict)
def Useraction(**meta):
def wrap(f):
cls= get_defining_class(f)
class_metadata[cls][f]= meta
return f
return wrap
推荐答案
您正在使用修饰符将元数据添加到方法。那很好。可以这样做,例如:
def user_action(description):
def decorate(func):
func.user_action = {'description': description}
return func
return decorate
现在,您希望收集该数据并以class_metadata[cls][f]= meta
的形式将其存储在全局词典中。为此,您需要找到所有修饰的方法及其类。
最简单的方法可能是使用元类。在元类中,您可以定义创建类时发生的情况。在本例中,检查类的所有方法,找到修饰的方法并将它们存储在字典中:
class UserActionMeta(type):
user_action_meta_data = collections.defaultdict(dict)
def __new__(cls, name, bases, attrs):
rtn = type.__new__(cls, name, bases, attrs)
for attr in attrs.values():
if hasattr(attr, 'user_action'):
UserActionMeta.user_action_meta_data[rtn][attr] = attr.user_action
return rtn
我将全局词典user_action_meta_data
放在元类中,只是因为它感觉合乎逻辑。它可以在任何地方。
现在,只需在任何类中使用它:
class X(metaclass=UserActionMeta):
@user_action('Exit the application')
def exit(self):
pass
静态UserActionMeta.user_action_meta_data
现在包含您需要的数据:
defaultdict(<class 'dict'>, {<class '__main__.X'>: {<function exit at 0x00000000029F36C8>: {'description': 'Exit the application'}}})
这篇关于用于保存有关类的元数据的修饰符的替代方案的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!