【问题标题】:Calling static method in python在python中调用静态方法
【发布时间】:2022-12-22 06:00:53
【问题描述】:

我有一个类 Person 和该类中的一个名为 call_person 的静态方法:

class Person:
    def call_person():
        print "hello person"

在 python 控制台中,我导入类 Person 并调用Person.call_person()。但它给我的错误是'module' object has no attribute 'call_person'。谁能告诉我为什么会出现此错误?

【问题讨论】:

标签: python static-methods


【解决方案1】:

您需要执行以下操作:

class Person:
    @staticmethod
    def call_person():
        print("hello person")

# Calling static methods works on classes as well as instances of that class
Person.call_person()  # calling on class
p = Person()
p.call_person()       # calling on instance of class

根据您想做什么,类方法可能更合适:

class Person:
    @classmethod
    def call_person(cls):
        print("hello person", cls)

p = Person().call_person() # using classmethod on instance
Person.call_person()       # using classmethod on class

这里的不同之处在于,在第二个示例中,类本身作为第一个参数传递给方法(与实例是第一个参数的常规方法或不接收任何其他参数的静态方法相反)。

现在回答你的实际问题。我敢打赌您找不到您的方法,因为您已将类 Person 放入模块 Person.py 中。

然后:

import Person  # Person class is available as Person.Person
Person.Person.call_person() # this should work
Person.Person().call_person() # this should work as well

或者,您可能希望从模块 Person 导入类 Person:

from Person import Person
Person.call_person()

关于什么是模块和什么是类,这一切都让人有些困惑。通常,我会尽量避免给类取与它们所在的模块相同的名称。但是,这显然并没有被看不起,因为标准库中的 datetime 模块包含一个 datetime 类。

最后,值得指出的是你不需要这个简单示例的类:

# Person.py
def call_person():
    print("Hello person")

现在在另一个文件中,导入它:

import Person
Person.call_person() # 'Hello person'

【讨论】:

  • 在实践中,使用 Python 将通常定义为 @staticmethod 的实用函数放入模块中的函数中是否更常见?
  • @ThomasFarvour——我的经验法则是如果你使用静态方法,你应该准备证明为什么作为静态方法比模块级函数更有意义。恕我直言,静态方法引人注目的用例非常少见,但它们确实偶尔会出现一次。
  • @mgilson Raymond Hettinger 认为,使方法成为 staticmethod 可以提高可查找性并有助于在正确的上下文中使用它。 (youtu.be/HTLu2DFOdTg?t=31m21s)
  • @Yurim——这可能是真的,但 Guido 认为 staticmethod 是个错误 (groups.google.com/forum/#!topic/python-ideas/McnoduGTsMw)。所以,我想每个人都应该选择他们想要订阅的核心开发人员的哲学;-)。正如我在评论中所说,我认为在某些情况下 staticmethod 可以(请参阅 Brett Cannon 在该线程上的评论),但我认为它们的传播范围并不广。那是我的意见,这也是为什么我将其归入评论部分而不是帖子的主体:-)
  • @mgilson 感谢您提供该链接。
【解决方案2】:

每个人都已经解释了为什么这不是静态方法,但我将解释为什么您找不到它。您正在寻找模块中的方法而不是类中的方法,因此类似这样的方法可以正确找到它。

import person_module
person_module.Person.call_person() # Accessing the class from the module and then calling the method

同样正如@DanielRoseman 所说,您可能会想象模块包含一个与 Java 同名的类,尽管在 Python 中并非如此。

【讨论】:

  • 好点——我想我应该回答实际问题 ;) (+1)。
  • @mgilson 你仍然可以添加这个
  • 实际上我怀疑 OP 根本不想要一个类,但是他认为来自 Java 的所有模块都必须包含一个同名的类。
  • @DanielRoseman——我认为你也是对的。很好的观察力。 (诸如此类的事情让我不想学习 Java;)。
【解决方案3】:

在 python 3.x 中,您可以声明一个静态方法,如下所示:

class Person:
    def call_person():
        print "hello person"

但是第一个参数为 self 的方法将被视为类方法:

def call_person(self):
    print "hello person"

在 python 2.x 中,您必须在静态方法之前使用 @staticmethod

class Person:
    @staticmethod
    def call_person():
        print "hello person"

您还可以将静态方法声明为:

class Person:
    @staticmethod
    def call_person(self):
        print "hello person"

【讨论】:

    【解决方案4】:

    那是不是静态方法;尝试

    class Person:
        @staticmethod
        def call_person():
            print "hello person"
    

    有关详细信息,请参阅here

    【讨论】:

    • 在 Python 3 中,OP 的定义定义一个静态方法,你能够从类对象调用而不需要类实例对象。如果有任何不使用装饰器的东西给你一个更“静态”的方法,因为你甚至不能从实例对象调用它。当你使用@staticmethod能够从类和类实例对象调用方法。
    【解决方案5】:

    您需要添加the decorator classmethod

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多