python一张图浓缩,任何人都可以帮助浓缩这个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, 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.

Can anyone see a way to condense this code?

解决方案

There are number of ways to do it: class decorator, metaclass, Mixin.

Common helper function:

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)))

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

Also you could manipulate attrs directly: attrs[name] = value before calling type() instead of setattr(cls, name, value).

The above assumes that QObject.__class__ is type.

Mixin

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.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值