Python 中从静态类引用父类

huangapple go评论81阅读模式
英文:

python refer to parent class from static class

问题

在静态类中是否可以访问父类的名称?例如,在下面的bar方法中如何打印父类的名称?

class Static:
    def bar(self):
        parent_name = ???
        print(parent_name)

class A:
    object = Static()

    def foo(self):
        A.object.bar()

class B:
     object = Static()

    def foo(self):
        B.object.bar()

A().foo()
B().foo()
英文:

Is it possible to access the parent class name within a static class? For example, how to I print the parent class name in the bar method below?

class Static:
    def bar(self):
        parent_name = ???
        print(parent_name)

class A:
    object = Static()

    def foo(self):
        A.object.bar()

class B:
     object = Static()

    def foo(self):
        B.object.bar()

A().foo()
B().foo()

答案1

得分: 3

以下是翻译好的部分:

您正在寻找__set_name__方法。

当类完成构建时,它会在每个静态属性上调用此方法。其中一个参数是“owner”类(A或B),所以您只需要存储该引用。请注意,这需要为每个父类创建一个单独的Static实例,但您已经在做了。

class Static:
    def bar(self):
        print(self.parent_name)

    def __set_name__(self, owner, name):
        self.parent_name = owner.__name__

class A:
    object = Static()

    def foo(self):
        A.object.bar()

class B:
    object = Static()

    def foo(self):
        B.object.bar()

A().foo()
B().foo()

我个人在可能的情况下避免使用这些魔术方法,因此您还可以考虑采纳@JonSG的建议,将所有者类放入Static构造函数中。这样,关系会更清晰,但需要在事后添加它们的成本。

class Static:
    def __init__(self, owner):
        self.parent_name = owner.__name__

    def bar(self):
        print(self.parent_name)

class A:
    def foo(self):
        A.object.bar()
A.object = Static(A)

class B:
    def foo(self):
        B.object.bar()
B.object = Static(B)

A().foo()
B().foo()

或者,您可以利用metaclass来完成一些工作。这有潜力简化A()B()的实现。

class Static:
    def __init__(self, parent_name) -> None:
        self.parent_name = parent_name

    def bar(self):
        print(self.parent_name)

class AB_Meta(type):
    def __init__(cls, name, bases, dct):
        cls.object = Static(name)

class A(metaclass=AB_Meta):
    def foo(self):
        A.object.bar()

class B(metaclass=AB_Meta):
    def foo(self):
        B.object.bar()

A().foo()
B().foo()

应该会给您:

A
B
英文:

You're looking for the __set_name__ method.

It is called on every static attribute of a class when the class is finished constructing. One of the parameters is the "owner" class (A or B), so all you need is to store that reference. Note that this requires a separate Static instance for each parent class, but you're doing that already.

class Static:
    def bar(self):
        print(self.parent_name)

    def __set_name__(self, owner, name):
        self.parent_name = owner.__name__

class A:
    object = Static()

    def foo(self):
        A.object.bar()

class B:
    object = Static()

    def foo(self):
        B.object.bar()

A().foo()
B().foo()

I personally avoid these magic methods when possible, so you might also consider taking @JonSG's advice and put the owner class in the Static constructor instead. This way the relationship is much clearer, at the cost of adding them after-the-fact.

class Static:
    def __init__(self, owner):
        self.parent_name = owner.__name__

    def bar(self):
        print(self.parent_name)

class A:
    def foo(self):
        A.object.bar()
A.object = Static(A)

class B:
    def foo(self):
        B.object.bar()
B.object = Static(B)

A().foo()
B().foo()

Alternatively, one might leverage a metaclass to do some of the work. This has the potential to also simplify the implementations of A() and B()

class Static:
    def __init__(self, parent_name) -> None:
        self.parent_name = parent_name

    def bar(self):
        print(self.parent_name)

class AB_Meta(type):
    def __init__(cls, name, bases, dct):
        cls.object = Static(name)

class A(metaclass=AB_Meta):
    def foo(self):
        A.object.bar()

class B(metaclass=AB_Meta):
    def foo(self):
        B.object.bar()

A().foo()
B().foo()

Should give you:

A
B

huangapple
  • 本文由 发表于 2023年7月17日 22:49:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76705656.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定