代码之家  ›  专栏  ›  技术社区  ›  Ludo

Python-调用时转换类属性

  •  0
  • Ludo  · 技术社区  · 8 年前

    假设我有以下课程

    class Headings:
        standard_heading = {
            'height': 3.72,
            'width': 25.68,
            'left': 1.65,
            'top': 0.28
        }
    

    例如,我想要以下所有值都乘以10的结果:

    Headings.standard_heading
    
    >>> {
                'height': 37.2,
                'width': 256.8,
                'left': 16.5,
                'top': 2.8
            }
    

    是否无法通过向类中添加类似的方法来覆盖对类属性的调用:

    def __getattribute__(cls, attr):
        return {k:v*10 for k,v in attr.items()
    

    我永远不会创建这个类的实例。我只是出于分组的目的使用它。

    谢谢

    3 回复  |  直到 8 年前
        1
  •  3
  •   kabanus    8 年前

    您几乎已经拥有了它-只需将它定义为一个类方法(还有一个小语法错误, attr 此处为字符串):

    class Headings:
        standard_heading = {
            'height': 3.72,
            'width': 25.68,
            'left': 1.65,
            'top': 0.28
        }          
        @classmethod
        def __getattribute__(cls,attr):
            return {k:v*10 for k,v in cls.__dict__[attr].items()}
    
    print(Headings().standard_heading)
    

    注意,您确实需要一个实际的实例来实现这一点,但这就是您在示例中使用的。这也会破坏在对象的任何方法(例如 __init__ ),所以要小心。一个简单的解决方法是覆盖:

    @classmethod
    def __getattribute__(cls,attr):
        try:
            return {k:v*10 for k,v in cls.__dict__[attr].items()}
        except: raise AttributeError(attr)
    def __getattr__(self,attr):
        return object.__getattribute__(self,attr)
    

    现在,如果您有:

    def __init__(self): self.a = 'abc'
    

    然后

    print(Headings().a)
    

    也会起作用。说明:

    1. 第一 __getattribute__ 作为类方法调用。
    2. 如果不存在类变量,则 __getattr__ 调用,现在作为常规方法调用,对实际对象(和对象成员)也是如此。
    3. 致电 object __getattribute(获取属性)__ 恢复正常行为。

    最后一点-如果您只想定义一个特殊的 getter 对于一个类成员,一种只会影响该成员的更安全的方法是使用 @property @getter -如中的示例所述 How does the @property decorator work? 谢谢 Adonis 为了指出这一点。

        2
  •  1
  •   Guybrush    8 年前

    如果要将此行为应用于许多不同的类,可以创建父类。

    class MultiplyBy10:
        def __getattribute__(self, attr):
            return {k:v*10 for k,v in super().__getattribute__(attr).items()}
    
    class Headings(MultiplyBy10):
        standard_heading = {
            'height': 3.72,
            'width': 25.68,
            'left': 1.65,
            'top': 0.28
        }
    
    h = Headings()
    print(h.standard_heading)
    

    将显示

    {'height': 37.2, 'width': 256.8, 'left': 16.5, 'top': 2.8000000000000003}
    
        3
  •  0
  •   Aabid Ali    8 年前

    如果您的要求是更改从字典返回的值,而不是创建另一个字典,那么您可能需要构建一个自定义字典-: How to "perfectly" override a dict?

    推荐文章