Python如何从类方法调用实例方法?

时间:2019-11-26 01:52:53

标签: python

我有以下代码:

class Player():
    """Initialization examples:
            player = Player('Lebron', 'James')
            player = Player.by_id(2544)
    """
    def __init__(self, first_name, last_name):
        """Search for a given player matching first_name and last_name.

        The matching is case insensitive.
        """
        self.player = self._get_player_by_name(
            first_name.lower(), last_name.lower())

    @classmethod
    def by_id(self, player_id):
        """Search for a given player by thier nba.com player id.

        Args:
            player_id: str representation of an nba.com player id
                e.g. Lebron's player id is 2544 and his nba.com link is
                    https://stats.nba.com/player/2544/

        Intended as an alternate Player constructor.
        """
        self.player = self._get_player_by_id(str(player_id))

    def _get_player_by_id(self, player_id):
        pass

但是,在调用Player.by_id(2544)时,出现以下错误:

TypeError: _get_player_by_id() missing 1 required positional argument: 'player_id'

这是怎么回事?我搜索的大多数问题都只涉及添加我已经拥有的self参数。

2 个答案:

答案 0 :(得分:1)

@classmethod使方法将类类型作为第一个参数,而不是特定的实例。例如,考虑以下代码:

class C:
    @staticmethod
    def a():
        # static methods take no implicit parameters
        print("a")

    @classmethod
    def b(cls):
        # class methods implicitly take the *class object* as the first parameter
        print("b", cls)

    def c(self):
        # instance methods implicitly take the instance as the first parameter
        print("c", self)

C().a()
C().b()
C().c()

此打印

a
b <class '__main__.C'>
c <__main__.C object at 0x103372438>

请注意,按照惯例,对于类方法,我们使用cls而不是self。这只是约定-调用此参数self并不能神奇地使其成为实例!

这意味着,在by_id中,当您调用self._get_player_by_id时,您正在调用Player._get_player_by_id-没有实例。这意味着player_id最终以“自我”的身份传递,从而导致您看到错误。

要解决此问题,您可能还希望_get_player_by_id成为类方法。

答案 1 :(得分:0)

by_id是一个类方法,通过使用类名调用该方法可以知道。

但是,此类方法然后调用实例特定的方法

_get_player_by_id.

正在发生的事情是,当运行_get_player_by_id时,您将提供player_id作为self的参数参数,而不是实际的player_id。

这很有意义,因为 self 是引用实例的,而不是类对象的。

您需要做的是,在您的 by_id 方法中,您需要传入Player实例,并将其与player_id一起传入get_player_by_id