【问题标题】:Is it possible to transform default class dunder methods into class methods?是否可以将默认的类 dunder 方法转换为类方法?
【发布时间】:2020-09-14 06:07:19
【问题描述】:

为了给你一些背景信息,昨天我遇到了this post。我发现这个问题很有趣,所以我试图找到一个解决方案,使语法尽可能接近所要求的内容。这是我想出的:

class DummyCube:
    cubes = []

    @classmethod
    def __getattribute__(cls, name):
        print('is this called?')
        attributes = [getattr(cube, name) for cube in cls.cubes]

        return attributes


class Cube:
    def __init__(self, volume):
        DummyCube.cubes.append(self)
        self.volume = volume


a = Cube(1)
b = Cube(2)
c = Cube(3)

print(DummyCube.__getattribute__('volume'))
print(DummyCube.volume)

我认为我的方法太复杂了(或者通常不是很好),尤其是与当前接受的答案相比,但幸运的是,这与我想知道的内容并不真正相关。

我的方法失败了,因为DummyCube.volume 引发了AttributeError: type object 'DummyCube' has no attribute 'volume',这当然是真的,但我不明白为什么我的自定义__getattribute__ 类方法没有被调用。直接调用该方法有效。根本不可能做到这一点吗?我在这里想念什么?据我了解,__getattribute__ 是在使用'.'-notation 时首先调用的,但错误回溯并没有让我确认这一点。

【问题讨论】:

  • 您需要将方法放在 meta 类上,而不仅仅是将其设为类方法,参见例如stackoverflow.com/questions/15214386/…
  • 我明白了。我不确定我是否理解为什么。你是说 super().__getattribute__ 方法是在我自己的实现之前调用的,从类级别调用它?
  • super() 代表基类(实际上是 MRO 中的下一个类)。元类不是基类。关系是issubclass(some_class, base_class)isinstance(some_class, meta_class)。在您的情况下,DummyCube 的基类是 object,它的元类是 type

标签: python class methods overriding magic-methods


【解决方案1】:

不知道这是否能解决您的问题。但是要调用您的 getattribute,您需要包含括号。

class Cube:
    def __init__(self, volume):
        DummyCube().cubes.append(self)
        self.volume = volume

【讨论】:

  • 括号实例化了DummyCube 类,但我想避免这种情况,因为我对类方法感兴趣。然而,一个有趣的建议!
【解决方案2】:

我明白了。我还在学习 Python,所以我的建议可能不是那么好。别担心这将是最后一个^^。我刚刚注意到这可能是您正在寻找的。​​p>

class DummyCube:
    cubes = []

    @classmethod
    def __getattribute__(cls, name):
        print('is this called?')
        attributes = [getattr(cube, name) for cube in cls.cubes]
        return attributes

class Cube:
    def __init__(self, volume):
        self.volume = volume
        DummyCube.cubes.append(self)
 
a = Cube(1)
b = Cube(2)
c = Cube(3)

print(DummyCube.__getattribute__('volume'))
print(DummyCube.cubes[0].volume)
print(DummyCube.cubes[1].volume)
print(DummyCube.cubes[2].volume)

顺便说一句。我仍然不明白这是如何工作的:)

【讨论】:

  • 我的方法不起作用的原因是因为DummyCube.volume没有调用__getattribute__()。您的案例有效,因为您正在访问 DummyCube.cubes 属性,这从来都不是问题。但感谢您试一试!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-08
  • 1970-01-01
  • 1970-01-01
  • 2011-03-24
  • 1970-01-01
相关资源
最近更新 更多