在Python2.7这个代码可以很好地工作,__getattr__在MetaTable
运行.但是在Python 3.5中它不起作用.
class MetaTable(type):
def __getattr__(cls, key):
temp = key.split("__")
name = temp[0]
alias = None
if len(temp) > 1:
alias = temp[1]
return cls(name, alias)
class Table(object):
__metaclass__ = MetaTable
def __init__(self, name, alias=None):
self._name = name
self._alias = alias
d = Table
d.student__s
Run Code Online (Sandbox Code Playgroud)
但是在Python 3.5中我得到了一个属性错误:
Traceback (most recent call last):
File "/Users/wyx/project/python3/sql/dd.py", line 31, in <module>
d.student__s
AttributeError: type object 'Table' has no attribute 'student__s'
Run Code Online (Sandbox Code Playgroud) 我有一个相当大的涉及装饰器来调试我想动态添加到类的PyQt信号.有没有办法动态地向类中添加装饰器?
我可能从错误的角度处理这个问题,所以这就是我想要完成的.
到目前为止,我已经考虑了几种可能的解决方案:
object和PyQt的内置QtCore.QObject)之外,这将很容易.我想我可以将这个装饰器附加到我的基类,一切都会按预期运行.但是,在这个特定的应用中并非如此.我不想将所有类更改为具有相同的基类.object或QtCore.QObject:我不知道这将如何实际工作.但是,从理论上讲,我可以将其中一个基类更改__init__为new_init我在装饰器中定义的吗?这看起来真的很危险,但也许这是一个好方法?__metaclass__属性添加到我想要将装饰器注入的类中.我认为这是不可能的,因为要插入此属性,必须已经构造了类.因此,我定义的任何元类都不会被调用.这是真的? 我尝试了一些元类魔法的变种,但似乎没有任何效果.我觉得使用元类可能是实现我想要的方式,但我似乎无法让它工作.
再说一遍,我可能会把这一切都搞错了.基本上我想将上面引用的装饰器中的行为附加到我的应用程序中的所有类(甚至可能是选择类的列表).另外,如果有必要,我可以重构我的装饰师.如果我用装饰器或其他机制附加此行为,我真的不在乎.我只是假设这个装饰器已经完成了我想要的单个类,所以可能很容易扩展.
我目前正在编写一个应用程序,允许用户通过"插件"类型架构扩展它.他们可以根据我提供的BaseClass对象编写其他python类,并根据各种应用程序信号加载这些类.在启动应用程序之前,作为插件加载的类的确切数量和名称是未知的,但仅在启动时加载一次.
在我研究解决这个问题的最佳方法的过程中,我提出了两个常见的解决方案.
选项1 - 使用imp,pkgutil等滚动自己.
例如,请参阅此答案或此答案.
选项2 - 使用插件管理器库
随机选择一对
我的问题是-在应用程序必须以加载新的插件重新启动条件-是否有过什么灵感来自上述方法的任何利益这个苏答案和这一个,如:
import inspect
import sys
import my_plugins
def predicate(c):
# filter to classes
return inspect.isclass(c)
def load_plugins():
for name, obj in inspect.getmembers(sys.modules['my_plugins'], predicate):
obj.register_signals()
Run Code Online (Sandbox Code Playgroud)
与上述方法相比,这种方法有任何缺点吗?(除了所有插件必须在同一个文件中)谢谢!
编辑
评论请求进一步的信息...我能想到的唯一额外的事情是插件使用闪烁库来提供他们订阅的信号.每个插件可以订阅不同类型的不同信号,因此必须具有其自己的特定"寄存器"方法.