【问题标题】:python - setting property of class on module loadingpython - 在模块加载时设置类的属性
【发布时间】:2012-11-29 05:20:54
【问题描述】:

我正在编写处理 python 上的 dict 数据的代码。 在实现这样的类时,我必须定义很多属性。这并不难,但最近我认为如果我可以使用辅助函数之类的东西会更好。

例如,假设我有一个像下面这样的类。

class MyClass(object):

    def __init__(self, data):
        self.data = data

    @property
    def version(self):
        return self.data["version"]

如果我可以像下面这样写这个类。

 class MyClass(object):

     def __init__(self, data):
         self.data = data

     define_own_property("data", "version")

看起来微不足道,但如果我能做到,我想我可以重用很多验证/异常处理案例。

有什么想法吗? :D

【问题讨论】:

    标签: python properties


    【解决方案1】:

    你可以通过编写一个函数来返回你想要的访问器来实现类似的功能:

    def define_own_property(attr, key):
        def prop(self):
            return getattr(self, attr)[key]
        return property(prop)
    
    class MyClass(object):
        def __init__(self, data):
            self.data = data
    
        version = define_own_property("data", "version")
    

    请注意,您必须这样做 version = ... 无法进行简单的函数调用 define_own_property 为正在定义的类添加属性,因为该类尚不存在,因此您无法引用它。

    另一种可能性是给你的类一个属性,它是一个列表或字典或包含相关参数(“数据”、“版本”等)的东西,然后编写一个读取这些参数并自动创建的类装饰器系列属性。这将完全消除在类内部定义属性的需要;您只需列出您希望属性访问的内容,并在类上使用一次装饰器。

    【讨论】:

    • 这很好。我想我比我更喜欢它。
    • @mgilson:呵呵,谢谢。你的基本上是一样的,除了使用property,你基本上重新实现了property,但内置了特定的get-key-of-attr行为。
    • 我知道。这就是为什么你的更好。为什么要重新发明轮子?但我要离开我的,因为我想看看描述符的实际示例是件好事。 (而且因为人们出于某种原因赞成它......)
    • 谢谢。我越来越习惯 python 的“一切都是对象”的概念。简单又好看。
    【解决方案2】:

    看来你可以使用描述符:

    class Descr(object):
        def __init__(self,attr,key):
            self.attr = attr
            self.key = key
    
        def __get__(self,obj,type=None):
            return getattr(obj,self.attr)[self.key]
    
        def __set__(self,obj,value):
            getattr(obj,self.attr)[self.key] = value
    
        def __delete__(self,obj):
            del getattr(obj,self.attr)[self.key]
    
    class MyClass(object):
        def __init__(self, data):
            self.data = data
    
        version = Descr("data","version")
        foobar = Descr("data","foobar")
    
    a = MyClass({})
    a.version = 1
    print a.version
    a.foobar = 'string'
    print a.data
    

    【讨论】:

      猜你喜欢
      • 2012-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-30
      • 1970-01-01
      • 2023-04-06
      • 1970-01-01
      相关资源
      最近更新 更多