如何在Python中为静态方法选择语法?

更新时间:2024-05-09 下载TXT文档 下载Word文档

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

将声明一个常规方法:

def mymethod(self, params)
   ...
   return

声明了一个静态方法:

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

如果您不添加静态方法行,编译器会抱怨自我丢失。

这是一种非常简单的非常简单的方法,在其他语言中只需使用关键字和声明语法。谁能告诉我这种语法的演变?这仅仅是因为课程被添加到现有语言中吗?

由于我可以将staticmethod行移动到类中的后期,因此它也表明了
解析器在记账方面做得更加努力。

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

  • 为何投票结果如何?+1。 这是一个有效的问题。 我认为它已经开始反过来了,即故意选择实例语法来要求显式传递self
  • 它是一个讨论/咆哮,而不是一个问题。 在python中,可以使用装饰器
  • @SilentGhost:对我而言,它更像是在设计决策背后的仪式,而不是咆哮。
  • 我试图在这里理解语言设计的基本原理。 在SO上有很多关于这些事情的问题。 如果让某人开心,我可以添加一个语言设计标签。
  • @Uri:你只是有点过时了,你现在应该使用装饰师这样做,这使得它更像其他语言。
  • @unwind:我正在编写一个必须支持一些遗留代码的库。 我一直在使用旧的语法来避免潜在的问题。

在类之后很久就将静态方法添加到Python中(很早就添加了类,甚至可能在1.0之前添加;静态方法直到大约2.0时才显示)。它们被实现为正常方法的修改,您从函数创建静态方法对象以获取静态方法,而编译器默认生成实例方法。

与Python中的许多内容一样,静态方法已经引入,然后在人们使用它们时进行了改进,并希望获得更好的语法第一轮是引入语义而不向语言添加新语法的一种方式(Python对语法更改非常有抵抗力)。我不是Guido,所以我不确定他脑子里发生了什么,这有些推测,但Python倾向于缓慢移动,逐步发展,并在他们获得更多经验时改进事物(特别是他们不喜欢添加一些东西,直到他们找到了正确的方法。这可能就是为什么从一开始就没有静态方法的特殊语法。

正如mjv所指出的那样,现在有一种更简单的方法,通过2.2或2.3中添加的称为"装饰器"的一些语法糖:

@staticmethod
def mystaticmethod(params)
    ...
    return

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

voyager和adurdin在他们之间做了很好的解释所发生的事情:随着Python 2.2中新风格的类和描述符的引入,出现了新的和深层的语义可能性 - 以及最明显有用的例子(静态方法,类方法)没有任何新语法的内置描述符类型支持(属性)(一旦新描述符充分证明了它们的实际用途,稍后会添加几个版本的装饰语法@foo)。我不是真的有资格引导Guido(当你需要他的时候是Tim Peters!),但我当时已经是Python的提交者并且参与了这些开发,我可以确认确实发生了什么。

旅行者对此的观察提醒他C是正确的目标:我一直声称Python比任何模仿C语法的语言都捕获了更多的"C精神"(括号,括号后if / while)等)。"C的精神"实际上是在ISO C标准的(非规范性)基本原理部分中描述的,并且包含五个原则(没有一个需要括号! - ),我声称Python匹配4.5(有几个视频在关于"Python for Programmers"的我的演示文稿,如果你很好奇,我会在这里介绍它。

特别是,C之灵的"只提供一种操作方式"与Python的"应该有一个 - 最好只有一个 - 显然是这样做的方式"相匹配 - 而C和Python,我相信,是唯一两种广泛采用这种设计理想的均匀性和非冗余的语言(它是一种理想的,并且不能明智地达到100% - 例如,如果a和b是整数,a + b和b +更好的是两种相同的方式来获得他们的总和! - ) - 但这是一个目标! - )。

  • Id仍然会调用+ b和b +"一种方法来执行它",因为在两种情况下它都是int + int。
  • 太糟糕了我不能接受两个答案;你的答案和迈克尔斯相得益彰。
  • @Alex:现在你让我迷上了。你能提供"Python for Programmers"的链接吗?我猜您是指这一个视频.google.com/videoplay?docid=1135114630744003385#
  • @voyager,多数民众赞成;对于精通程序员来说也是"无痛的python",对于第1部分我是youtube.com/watch?v=bDgD9whDfEY而我不知道第2部分隐藏在哪里(但我也确实知道它在youtube上的某个地方......)。
  • @Alex:我会以某种方式找到它;)第一个非常好。你是我今天睡了一个半小时的责任:)
  • "精通程序员的无痛Python"第2部分youtube.com/watch?v=y7vwZ20SDzc&feature=related
  • 感谢@voyager的调查!

python中的静态方法可以追溯到Python 2.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..."

在Python 2.2中,许多类系统被重新考虑并重新设计为"新式类" - 继承自object的类。新式类的一个特性是"描述符",实质上是类中的一个对象,负责描述,获取和设置类的属性。描述符有一个__get__方法,它传递类和实例,并应返回类或实例的请求属性。 短码网 duanma.net

描述符使得可以使用单个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

将此与普通方法的假设pure-python描述符进行比较,该方法默认用于类属性中的所有普通函数(这不是从实例查找方法时发生的情况,但它确实处理自动'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)时,您实际上正在创建一个新的描述符,其作用是不更改原始函数,并将此描述符存储在类的"method"属性中。

如果这只是为了让原来的功能恢复而做的很多工作 - 你是对的,那就是。但由于普通方法调用是默认情况,因此需要单独实现静态方法和类方法,并且描述符提供了使用一个简单API启用这些和其他复杂行为的方法。

正如其他人已经指出的那样,Python 2.4中引入的装饰器语法提供了一种更方便的方法来声明静态方法,但它只是一种语法上的方便,并没有改变静态方法的工作方式。

有关新式的更多详细信息,请参见http://www.python.org/doc/2.2.3/whatsnew/sect-rellinks.html和http://users.rcn.com/python/download/Descriptor.htm类和描述符。

Guido一直对在语言中添加新结构持谨慎态度。当提出静态方法时,表明你已经可以做到(自2.2以来有一个staticmethod()装饰器),你只是没有它的语法糖。

如果您阅读PEP,您可以看到添加内容的所有讨论。就我而言,就像那种做法一样。它让我想起C,因为没有不必要的关键字。

当添加到Python 2.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,这是一种静态方法。

  • 配方+1

Python中的静态方法情况是一流一切设计决策的直接结果,一切都是可执行语句。正如其他人所说的那样,静态方法只能通过Python 2.2描述符协议允许的新语义使用,并且在Python 2.4中使用函数装饰器使语法更加甜美。有一个简单的原因可以解释为什么静态方法很少受到关注 - 它们不会以任何方式扩展语言的功能并使语法稍微好一点。从语义上讲,它们相当于普通的旧函数。这就是为什么只有当语言的力量增长到足以使其在其他语言功能方面可实现时才实现它们。

从Python 2.4开始,还可以使用装饰器,如:

   @staticmethod
   def mystaticethod(params)
      ...
      return

但我对该功能的起源没有任何见解,正如在语言中实施的那样。但话说回来,我不是荷兰人:-)在这篇文章中看到Michael E的回答,关于静态方法在Python发展中的??到来。

BTW,尽管它们简单,但是

 @MyDeco
 someObject

   is merely"syntactic sugar" for

  MyDeco(someObject)

装饰者可以用于许多其他很酷的事情!

  • 我的理解是装饰器只能使用2.4及更高版本,因此它们之后会出现因为语法就是这样。我仍然想知道为什么语法是这样的。

Guido写博客The History of Python。我认为有一种方法可以与他联系,要求扩展这一特定主题。

  • 不知道那个博客,谢谢你的参考!

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

以上就是短码网小编为大家整理的《如何在Python中为静态方法选择语法?》相关内容,希望大家喜欢。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。

如若内容造成侵权/违法违规/事实不符,请将联系本站反馈,一经查实,立即处理!

如何在Python中为静态方法选择语法?》文档下载仅供参考学习,下载后请在24小时内删除。

转载注明出处:https://www.duanma.net/article/846978fa204.html

回到顶部