代码之家  ›  专栏  ›  技术社区  ›  Uri

Python中静态方法的语法是如何选择的?

  •  14
  • Uri  · 技术社区  · 16 年前

    我使用Python已经有一段时间了,我发现将方法声明为静态的语法很特别。

    将声明一个常规方法:

    def mymethod(self, params)
       ...
       return
    

    def mystaticethod(params)
       ...
       return
    mystaticmethod = staticmethod(mystaticmethod)
    

    如果不添加静态方法行,编译器会抱怨self-missing。

    这是一种非常复杂的方法,在其他语言中,只需使用关键字和声明语法即可完成非常简单的操作。有人能告诉我这种语法的演变吗?这仅仅是因为类被添加到了现有的语言中吗?

    因为我可以将staticmethod行移动到类的后面,所以它还建议

    注意,我知道后来添加的decorator语法,我想从语言设计的角度了解原始语法是如何产生的。我唯一能想到的是staticmethod应用程序调用一个将函数对象转换为静态方法的操作。

    8 回复  |  直到 16 年前
        1
  •  12
  •   Michael Ekstrand    16 年前

    在类被添加很久之后,静态方法就被添加到Python中(类很早就被添加了,甚至可能在1.0之前;静态方法直到2.0版才出现。它们是作为普通方法的修改实现的——您可以从函数创建一个静态方法对象来获得一个静态方法,而编译器默认生成实例方法。

    与Python中的许多东西一样,静态方法也被引入,然后随着人们使用它们并希望获得更好的语法而被细化。第一轮是在不向语言中添加新语法的情况下引入语义的一种方式(Python非常抵制语法更改)。我不是Guido,所以我不确定他脑子里到底在想什么,这有点推测性,但是Python倾向于缓慢地移动,增量地开发,并随着他们获得更多的经验而细化(特别是,在找到正确的方法之前,他们不喜欢添加东西)。这可能就是为什么从一开始就没有针对静态方法的特殊语法)。

    不过,正如mjv所指出的,现在有一种更简单的方法,通过在2.2或2.3中添加一些语法sugar,称为“decorators”:

    @staticmethod
    def mystaticmethod(params)
        ...
        return
    

    @staticmethod 语法是放东西的糖分 mystaticmethod = staticmethod(mystaticmethod) 在方法定义之后。

        2
  •  11
  •   Alex Martelli    16 年前

    voyager和adurdin在解释发生了什么方面做得很好:随着Python 2.2中引入了新样式的类和描述符,出现了新的深层语义可能性——最明显有用的示例(静态方法、类方法、属性)由内置描述符类型支持 没有任何新语法 (语法) @foo 在新的描述符充分证明了它们在现实世界中的实用性之后,for decorators在随后的几个版本中被添加。我真的没有资格为Guido频道(当你需要Tim Peters时,他在哪里!-),但我当时已经是Python的提交者,并且参与了这些开发,我可以证实这确实发生了。

    voyager在这一点上的观察提醒了他C语言是正确的:我早就宣称Python比任何模仿C语言的语言捕捉到更多的“C精神” of C(如果/while后面的大括号、括号等)。”“C”的精神实际上在ISO C标准的(非规范性)基本原理部分进行了描述,包括五项原则(无需括号!)其中我声称Python与4.5相匹配(如果你好奇的话,我在网上有几个关于“程序员用Python”的演示视频,我会在这里介绍这一点)。

        3
  •  4
  •   adurdin    16 年前

    python中的静态方法可以追溯到Python2.2中引入所谓的新样式类。在此之前,类上的方法只是普通函数,存储为类上的属性:

    class OldStyleClass:
        def method(self):
            print "'self' is just the first argument of this function"
    
    instance = OldStyleClass()
    OldStyleClass.method(instance) # Just an ordinary function call
    print repr(OldStyleClass.method) # "unbound method..."
    

    instance.method() # 'instance' is automatically passed in as the first parameter
    print repr(instance.method) # "bound method..."
    

    在Python2.2中,类系统的大部分被重新思考并重新设计为继承自 object . 新型类的特征之一是描述符,本质上是类中负责描述、获取和设置类属性的对象。描述符具有 __get__

    描述符使使用单个API实现类属性(如属性、类方法和静态方法)的复杂行为成为可能。例如 staticmethod 描述符可以这样实现:

    class staticmethod(object):
        """Create a static method from a function."""
    
        def __init__(self, func):
            self.func = func
    
        def __get__(self, instance, cls=None):
            return self.func
    

    将其与普通方法的假设纯python描述符进行比较,普通方法默认用于classes属性中的所有普通函数(从实例进行方法查找时,情况并非如此,但它确实处理自动“self”参数):

    class method(object):
        """Create a method from a function--it will get the instance
        passed in as its first argument."""
    
        def __init__(self, func):
            self.func = func
    
        def __get__(self, instance, cls=None):
            # Create a wrapper function that passes the instance as first argument
            # to the original function
            def boundmethod(*args, **kwargs):
                return self.func(self, *args, **kwargs)
            return boundmethod
    

    method = staticmethod(method)

    如果为了恢复原来的函数你需要做很多工作,那么你是对的。但是,由于正常的方法调用是默认情况,静态方法和类方法需要单独实现,描述符提供了一种方法,可以通过一个简单的API实现这些和其他复杂行为。

    正如其他人已经指出的,Python2.4中引入的decorator语法为声明静态方法提供了一种更方便的方法,但它只是一种语法上的方便,并不会改变静态方法的工作方式。

    看见 http://www.python.org/doc/2.2.3/whatsnew/sect-rellinks.html http://users.rcn.com/python/download/Descriptor.htm

        4
  •  3
  •   Jim Ferrans    14 年前

    you could already do it (有一个 staticmethod() decorator since 2.2 ),你只是没有语法上的糖分。

    如果你阅读政治公众人物,你可以看到所有关于添加内容的讨论。一、 首先,像这样的方法。它使我想起 C 因为没有不必要的关键字。

    当新的修饰符语法添加到Python2.4中时,您可以使用具有更干净语法的现有修饰符。

    无论如何,如果你必须维护一个旧的系统,它们也没什么不同。

    #>2.4
    class MyClass(object):
        @staticmethod
        def mystaticmethod(params)
            pass
            return
    
    #<2.4
    class MyClass(object):
    
        def mystaticmethod(params)
            '''Static Method'''
            pass
            return
        staticmethod(mystaticmethod)
    

    我建议您在静态方法中添加注释或docstring 尖叫 这是一种静态方法。

        5
  •  2
  •   Ants Aasma    16 年前

    Python中的静态方法情况是设计决策的直接结果 first-class everything everything is an executable statement

        6
  •  2
  •   mjv    16 年前

    从Python2.4开始,还可以使用 decorator

       @staticmethod
       def mystaticethod(params)
          ...
          return
    

    但是,对于这个特性的起源,我没有任何见解,因为它是在语言中实现的。但是,再一次,我不是荷兰人:-)请看Michael E在这篇文章中的回应,关于Python进化中静态方法的出现较晚。

     @MyDeco
     someObject
    
       is merely "syntactic sugar" for
    
      MyDeco(someObject)
    

    装饰师可以用来做很多其他很酷的事情!

        7
  •  1
  •   SilentGhost    16 年前

    Guido写博客 The History of Python . 我认为有一种方法可以联系他,要求他就这个特定的话题展开讨论。

        8
  •  0
  •   NawaMan    16 年前

    也许,设计最初并不认为在可以使用函数时需要静态方法。因为python没有数据隐藏,所以实际上不需要静态方法,而不用类作为名称空间。

    推荐文章