8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

为什么要使用@staticmethod?

user303749 2月前

97 0

我只是不明白为什么我们需要使用@staticmethod。让我们从示例开始。class test1:def __init__(self,value): self.value=value @staticmethod def static_add_one(val...

我只是不明白为什么我们需要使用@staticmethod。让我们从一个例子开始。

class test1:
    def __init__(self,value):
        self.value=value

    @staticmethod
    def static_add_one(value):
        return value+1

    @property
    def new_val(self):
        self.value=self.static_add_one(self.value)
        return self.value


a=test1(3)
print(a.new_val) ## >>> 4



class test2:
    def __init__(self,value):
        self.value=value

    def static_add_one(self,value):
        return value+1

    @property
    def new_val(self):
        self.value=self.static_add_one(self.value)
        return self.value


b=test2(3)
print(b.new_val) ## >>> 4

上面的例子中,两个类中的方法 static_add_one 在计算时不需要类的实例(self)。

类中的 static_add_one 方法 test1 被修饰 @staticmethod 并正常工作。

但同时, static_add_one 在参数中提供但根本不使用它 test2 的技巧, @staticmethod 没有 self 类中的

那么使用 有什么好处呢 @staticmethod ?它会提高性能吗?还是仅仅是因为 Python 的禅宗说“ 显式优于隐式 ”?

帖子版权声明 1、本帖标题:为什么要使用@staticmethod?
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由user303749在本站《oop》版块原创发布, 转载请注明出处!
最新回复 (0)
  • @Ignacio Vazquez-Abrams 有些方法不需要类,但类需要这些方法来执行一些计算。我应该把这些方法放在哪里?模块级?或者你的意思是我应该编写像 get_new_value() 和 set_new_value(value) 这样的函数来直接与类的实例交互?

  • 之所以要使用, staticmethod 是因为如果您有可以作为独立函数(不属于任何类)编写的内容,但又想将其保留在类中,因为它在语义上与类有某种关联。(例如,它可能是一个不需要来自类的任何信息的函数,但其​​行为特定于类,因此子类可能想要覆盖它。)在许多情况下,将某些内容编写为独立函数而不是静态方法同样有意义。

    你的例子其实并不一样。一个关键的区别是,即使你不使用 self ,你仍然需要一个实例来调用 static_add_one --- 你不能直接用 调用类 test2.static_add_one(1) 。所以那里的行为确实不同。静态方法最严重的“竞争对手”不是忽略 的常规方法 self ,而是一个独立的函数。

  • +1 这正是目标。我们使用静态方法将常规函数附加到类。这提高了与类密切相关但不依赖于该类的函数的可查找性。

  • 因此,如果一个函数具有两个特征 - 独立和语义上与类相关。为了遵循语义相似性的特征,我应该将其放在类中。为了遵循独立性的特征,我应该使用 @staticmethod 装饰器,而不是在其中传递一个虚拟的 self 参数,因为 self 参数会以某种方式淡化其独立性的颜色。但毕竟,性能提升不大,对吧?

  • @user2720402:如果我理解正确的话,大致上是的。性能不是使用或不使用静态方法的理由。您应该根据函数与类的概念关系(或缺乏这种关系)来选择是否使用静态方法。

  • 即使我不添加 @staticmethod,函数在没有装饰器的情况下仍然可以工作。这样做有什么好处吗?

  • 今天我突然发现使用 @staticmethod .

    如果在类中创建了静态方法,则无需在使用该静态方法之前创建该类的实例。

    例如,

    class File1:
        def __init__(self, path):
            out=self.parse(path)
    
        def parse(self, path):
            ..parsing works..
            return x
    
    class File2:
        def __init__(self, path):
            out=self.parse(path)
    
        @staticmethod
        def parse(path):
            ..parsing works..
            return x
    
    if __name__=='__main__':
        path='abc.txt'
        File1.parse(path) #TypeError: unbound method parse() ....
        File2.parse(path) #Goal!!!!!!!!!!!!!!!!!!!!
    

    由于方法 parse 与类 File1 File2 ,因此将其放在类中更为自然。但是,有时 parse 在某些情况下,此方法也可能用于其他类。如果要使用 来执行此操作 File1 调用方法之前 File1 创建 的实例 parse 。在类中使用静态方法时 File2 ,可以使用语法直接调用该方法 File2.parse .

    这使得您的工作更加方便、自然。

  • @classmethod 也同样如此。区别在于 @classmethods 传递的是类实例,而 @staticmethods 不传递任何特殊内容。

  • 我将补充其他答案未提及的内容。这不仅是模块化的问题,将某些东西放在其他逻辑相关部分旁边。此外,该方法在层次结构的其他点(即在子类或超类中)可以是非静态的,从而参与多态性(基于类型的调度)。因此,如果将该函数放在类之外,则将阻止子类有效地覆盖它。现在,假设您意识到您不需要 self 类的 C.f 函数 C ,您有三个选项:

    1. p1

    2. p2

    3. p3

    选项 2 需要的概念包袱较少(您已经必须了解 self 和方法作为绑定函数,因为这是更一般的情况)。但您可能仍然希望明确表示 self 不使用(解释器甚至可以奖励您一些优化,而不必将函数部分应用于 self )。在这种情况下,您可以选择选项 3 并 @staticmethod 在函数顶部添加。

  • 用于 @staticmethod 不需要对特定对象进行操作但仍希望位于类范围内(而不是模块范围)的方法。

    中的示例 test2.static_add_one 浪费了传递未使用的参数的时间 self ,但其他方面与 相同 test1.static_add_one 。请注意,这个无关的参数无法通过优化消除。

    我能想到的一个例子是我有一个 Django 项目,其中模型类代表一个数据库表,而该类的对象代表一条记录。该类使用的一些函数是独立的,不需要对象来操作,例如将标题转换为 \'slug\' 的函数,这是遵循 URL 语法所施加的字符集限制的标题表示。将标题转换为 slug 的函数被声明为 precise, staticmethod 以将其与使用它的类紧密关联。

  •  Explicit is better than implicit?
    

    相反,装饰器允许像调用 普通类方法 。因此,在阅读调用代码时,它实际上是一个静态方法的事实被掩盖了。

    之所以要使用这个函数,可能正是因为开发人员不必担心是否包含或省略 \'self\'。这可以节省在静态方法需要成为类方法后更改调用代码的时间。

    class Test:
    
        @staticmethod
        def method():
            print('base')
    
    
    class Derived(Test):
    
        def method(self):
            print('derived')
    
    
    t = Test()
    t.method()         # Success, but would fail without decorator
    Test.method()      # Success, with or without decorator
    
    d = Derived()
    d.method()         # Success with or without decorator
    Derived.method()   # Always fails, this is no longer a static method
    
  • 引用 13

    我认为你说到点子上了:

    但同时, static_add_one 在参数中提供但根本不使用它 test2 的技巧, @staticmethod 没有 self 类中的

    正如您所说, @staticmethod 提供 self 参数,以便您可以从实例而不是类调用方法,而不必显式编写参数 self 。根据 https://docs.python.org/3/library/functions.html#staticmethod :

    静态方法可以在类(如 C.f() )或实例(如 C()上调用。f() ).

    为了 C().f() 工作,您要么需要 f() @staticmethod (或明确调用 staticmethod() )来装饰,要么明确添加 self 参数,就像您在示例中所做的那样。

返回
作者最近主题: