任何人都可以帮助浓缩这个Python代码? [英] Can anyone help condense this Python code?

查看:117
本文介绍了任何人都可以帮助浓缩这个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期望类方法存在于类本身,而不是实例。移动 __ 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆