簡體   English   中英

Python:重載實例方法和 Class 方法/從 Class 方法訪問實例變量

[英]Python: Overload Instance Method and Class Method/ Access Instance Variable from Class Method

我想知道在 Python 中實現以下設計的最佳方法是什么:

class Executor:
    def __init__(self):
        self.val = 5

    def action(self):
        self.action(self.val)

    @classmethod
    def action(cls, val):
        print(f"Val is: {val}")

我希望能夠訪問該方法,既可以作為使用 object 初始化的值的實例方法,也可以作為使用傳入變量的 class 方法訪問該方法。 這是我想調用它的方式的示例:

>>> Executor.action(3)
Val is: 3
>>> Executor().action()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: action() missing 1 required positional argument: 'val'

我正在考慮嘗試使用關鍵字 arguments,但我似乎也無法讓它工作。 到目前為止,這是我的代碼:

class Executor:
    def __init__(self):
        self.val = 5

    @classmethod
    def action(cls, val=None):
        if val is None:
            # This doesn't work; cls does not have attribute 'val'.
            if hasattr(cls, "val"):
                print(f"Val from instance: {cls.val}")

            else:
                raise ValueError("Called as class method and val not passed in.")

        else:
            print(f"Val passed in: {val}")


>>> Executor.action(3)
Val passed in: 3
>>> Executor().action()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<input>", line 13, in action
ValueError: Called as class method and val not passed in.

但是 class 實例沒有可供訪問的 val。

我唯一能想到的另一件事是使用匈牙利符號,但這並不理想,因為它有點混亂,這意味着有多個方法名稱。

class Executor:
    def __init__(self):
        self.val = 5

    def action_instance(self):
        self.action_class(self.val)

    @classmethod
    def action_class(cls, val):
        print(f"Val is: {val}")


>>> Executor.action_class(3)
Val is: 3
>>> Executor().action_instance()
Val is: 5

任何關於可靠、干凈的方法的建議將不勝感激!

干杯。

你想做的事情對我來說很奇怪,我不確定你是否需要。 Python 不能通過方法簽名/類型重載,盡管有functools.singledispatch 因此,通過第二次定義action ,您實際上是在替換方法的第一個定義。

可觀察的行為可以通過以下方式實現:

class Executor:

    @classmethod
    def action(cls, val=5):
        return val

print(Executor().action())
print(Executor.action(3))

輸出:

5
3

But again check first that you really need something like that, because it breaks one of the expectations of Python coders and Python data model: calling a method through the class is equivalent to calling the method through the instance given that you pass the instance to the class 方法。

obj = Executor()
obj.action() # this is the same as Executor.action(obj)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM