任何人都可以帮助浓缩这个Python代码? [英] Can anyone help condense this Python code?
问题描述
我在使用Python写一个脚本,并有一个问题:
I'm writing a script in Python and have a bit of a problem:
class LightDMUser(QObject):
def __init__(self, user):
super(LightDMUser, self).__init__()
self.user = user
@pyqtProperty(QVariant)
def background(self): return self.user.get_background()
@pyqtProperty(QVariant)
def display_name(self): return self.user.get_display_name()
@pyqtProperty(QVariant)
def has_messages(self): return self.user.get_has_messages()
@pyqtProperty(QVariant)
def home_directory(self): return self.user.get_home_directory()
@pyqtProperty(QVariant)
def image(self): return self.user.get_image()
@pyqtProperty(QVariant)
def language(self): return self.user.get_language()
@pyqtProperty(QVariant)
def layout(self): return self.user.get_layout()
@pyqtProperty(QVariant)
def layouts(self): return self.user.get_layouts()
@pyqtProperty(QVariant)
def logged_in(self): return self.user.get_logged_in()
@pyqtProperty(QVariant)
def name(self): return self.user.get_name()
@pyqtProperty(QVariant)
def real_name(self): return self.user.get_real_name()
@pyqtProperty(QVariant)
def session(self): return self.user.get_session()
正如你所看到的,这个代码是非常多余的。我试着这样浓缩:
As you can see, this code is horribly redundant. I tried condensing it like this:
class LightDMUser(QObject):
attributes = ['background', 'display_name', 'has_messages', 'home_directory', 'image', 'language', 'layout', 'layouts', 'logged_in', 'name', 'real_name', 'session']
def __init__(self, user):
super(LightDMUser, self).__init__()
self.user = user
for attribute in self.attributes:
setattr(self, attribute, pyqtProperty(QVariant, getattr(self.user, 'get_' + attribute)))
然而,PyQt4期望类方法存在于类本身,而不是实例。移动 __ init __
块中的 setattr
代码不起作用,因为 self
没有为类定义,所以我真的不知道该怎么做。
PyQt4, however, expects the class methods to be present for the class itself, not an instance. Moving the setattr
code out of the __init__
block didn't work either because self
wasn't defined for the class, so I don't really know what to do.
任何人都可以看到一个方法来压缩这段代码? / p>
Can anyone see a way to condense this code?
推荐答案
有很多方法可以做到:class decorator,metaclass,Mixin。
There are number of ways to do it: class decorator, metaclass, Mixin.
通用辅助函数:
def set_pyqtproperties(klass, properties, proxy='user'):
def make_prop(prop):
def property_(self):
return getattr(getattr(self, proxy), 'get_' + prop)
property_.__name__ = prop
return property_
if isinstance(properties, basestring):
properties = properties.split()
for prop in properties:
setattr(klass, prop, pyqtProperty(QVariant, make_prop(prop)))
类装饰器
$ b b
Class decorator
def set_properties(properties):
def decorator(klass):
set_pyqtproperties(klass, properties)
return klass
return decorator
用法
Usage
@set_properties("display background")
class LightDMUser(QObject): pass
支持类装饰器,那么你可以尝试:
if there is no support for class decorators then you could try:
class LightDMUser(QObject):
pass
LightDMUser = set_properties("display background")(LightDMUser)
元类
Metaclass
def set_properties_meta(properties):
def meta(name, bases, attrs):
cls = type(name, bases, attrs)
set_pyqtproperties(cls, properties)
return cls
return meta
用法
Usage
class LightDMUser(QObject):
__metaclass__ = set_properties_meta("display background")
注意:如果将属性列表设置为类属性,您可以重用相同的元类:
Note: you could reuse the same metaclass if you set the list of properties as a class attribute:
def MetaClass(name, bases, attrs):
cls = type(name, bases, attrs)
set_pyqtproperties(cls, attrs.get('properties', ''))
return cls
class LightDMUser(QObject):
properties = "display background"
__metaclass__ = MetaClass
也可以直接操作 attrs
: attrs [name] =在调用
type()
而不是 setattr(cls,name,value)
之前调用
Also you could manipulate attrs
directly: attrs[name] = value
before calling type()
instead of setattr(cls, name, value)
.
上述假设 QObject .__ class__是
类型。
def properties_mixin(classname, properties):
#note: create a new class by whatever means necessary
# e.g., even using exec() as namedtuple does
# http://hg.python.org/cpython/file/3.2/Lib/collections.py#l235
# reuse class decorator here
return set_properties(properties)(type(classname, (), {}))
用法
Usage
PropertiesMixin = properties_mixin('PropertiesMixin', 'display background')
class LightDMUser(PropertiesMixin, QObject): pass
我没有尝试过。代码在这里显示实现该功能可能需要的代码的数量和种类。
I haven't tried any of it. The code is here to show the amount and the kind of code it might require to implement the feature.
这篇关于任何人都可以帮助浓缩这个Python代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!