当前位置: 首页 > 面试题库 >

指向Python中静态方法的指针

司马越
2023-03-14
问题内容

为什么在下面的代码中,使用类变量作为方法指针会导致未绑定的方法错误,而使用普通变量则可以正常工作:

class Cmd: 
    cmd = None

    @staticmethod   
    def cmdOne():
        print 'cmd one'

    @staticmethod   
    def cmdTwo():
        print 'cmd two'

def main():
    cmd = Cmd.cmdOne
    cmd() # works fine

    Cmd.cmd = Cmd.cmdOne        
    Cmd.cmd() # unbound error !!

if __name__=="__main__":
    main()

完整错误:

TypeError: unbound method cmdOne() must be called with Cmd instance as 
           first argument (got nothing instead)

问题答案:

我喜欢从下至上查看这种行为。

Python中的函数充当“描述符对象”。因此,它具有一种__get__()方法。

对具有此类__get__()方法的类属性的读取访问将“重定向”到该方法。对类的属性访问以方式执行attribute.__get__(None, containing_class),而对实例的属性访问则映射到attribute.__get__(instance, containing_class)

函数的__get__()方法的任务是将函数包装在一个方法对象中,该对象将包装self参数-对于对实例的属性访问而言。这称为绑定方法。

在2.x上进行类属性访问时,函数__get__()将返回一个未绑定的方法包装器,而正如我今天所了解的那样,在3.x上它将返回自身。(请注意,该__get__()机制在3.x中仍然存在,但是函数只是返回自身。)如果您看一下如何调用它,则几乎是相同的,但是未绑定的方法包装器还会检查self参数的正确类型。

一个staticmethod()呼叫只是创建一个对象,它__get__()调用用于返回最初给出的对象,使其撤销所描述的行为。这就是HYRY的诀窍的工作方式:属性acces取消staticmethod()包装,调用再次进行该操作,以便“新”属性与旧属性具有相同的状态,尽管在这种情况下,staticmethod()似乎应用了两次(但实际上不是)
)。

(顺便说一句:它甚至可以在这种怪异的情况下工作:

s = staticmethod(8)
t = s.__get__(None, 2) # gives 8

虽然8不是函数,2也不是类。)

在您的问题中,您有两种情况:

cmd = Cmd.cmdOne
cmd() # works fine

访问该类并询问其cmdOne属性,即staticmethod()对象。通过其查询__get__()并返回原始函数,然后调用原始函数。这就是为什么它可以正常工作的原因。

Cmd.cmd = Cmd.cmdOne
Cmd.cmd() # unbound error

执行相同的操作,但是将此功能分配给Cmd.cmd。下一行是属性访问-
再次__get__()执行对函数本身的调用,因此返回未绑定的方法,必须以正确的self对象作为第一个参数来调用该方法。



 类似资料:
  • 问题内容: Python中是否可以有无需初始化类即可调用的静态方法,例如: 问题答案: 是的,使用装饰器 请注意,某些代码可能使用旧的方法来定义静态方法,而将其staticmethod用作函数而不是装饰器。仅当你必须支持Python的旧版本(2.2和2.3)时,才应使用此选项。 这与第一个示例完全相同(使用),只是不使用漂亮的装饰器语法 最后,要谨慎使用!在极少数情况下,Python中需要使用静态

  • 问题内容: 我是Java菜鸟。我已经掌握了将C / C ++指针转换为Java引用的概念,并且进展相当顺利。 我打了一段有指针的代码(即* ptr)。我需要取消引用指针并更改其指向的指针的值(即 ptr =&newthing;) 在Java中这似乎要困难得多。是否有人对如何解决此问题有任何想法?快速谷歌搜索什么都没有。 这是C ++中的代码示例。我想在Java中获得类似的工作,但是ptr_to_p

  • 在下面给出的代码中,我声明了一个指向int的指针,我们都知道memcpy返回一个指向目标字符串的空指针,所以如果ptr是指向int的指针,那么为什么printf(“%s”,ptr);是完全有效的,ptr毕竟不是指向char的指针。

  • C++ 类 & 对象 一个指向 C++ 类的指针与指向结构的指针类似,访问指向类的指针的成员,需要使用成员访问运算符 ->,就像访问指向结构的指针一样。与所有的指针一样,您必须在使用指针之前,对指针进行初始化。 下面的实例有助于更好地理解指向类的指针的概念: #include <iostream> using namespace std; class Box { public:

  • 本文向大家介绍python的类方法和静态方法,包括了python的类方法和静态方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了python的类方法和静态方法。分享给大家供大家参考。具体分析如下: python没有和C++中static关键字,它的静态方法是怎样的呢?还有其它语言中少有的类方法又是神马? python中实现静态方法和类方法都是依赖于python的修饰器来实现的。 大家注意

  • 指针可以指向一份普通类型的数据,例如 int、double、char 等,也可以指向一份指针类型的数据,例如 int *、double *、char * 等。 如果一个指针指向的是另外一个指针,我们就称它为 二级指针,或者 指向指针的指针。 假设有一个 int 类型的变量 a,p1是指向 a 的指针变量,p2 又是指向 p1 的指针变量,它们的关系如下图所示: 将这种关系转换为C语言代码: 指针变