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

Python-类方法()

  •  0
  • Phoenix  · 技术社区  · 12 年前

    阅读Python标准库。试图理解classmethod。

    class C:
        @classmethod
        def f(x,y):
            print('words')
    

    当我键入:

    print(classmethod(C))
    

    它返回:

    <classmethod object at 0x00FAD930>
    

    如何查看classmethod返回什么而不是classmethod的生成器?

    4 回复  |  直到 12 年前
        1
  •  4
  •   Martijn Pieters    12 年前

    您正在生成 classmethod 描述符对象:

    print(classmethod(C))
    

    返回类 C 包裹在新的 分类法 对象这不是生成器,这是Python在用它修饰方法时实际存储在类中的内容。

    记住 @decorator_expression 函数或类上方的行只是替换该对象的额外函数调用的语法糖; @classmethod 在上面 def f(...) 这意味着Python将取代 f 具有 f = classmethod(f) .

    在查看 C.__dict__['f'] 价值这是相同类型的对象:

    >>> class C:
    ...     @classmethod
    ...     def f(x,y):
    ...         print('words')
    ... 
    >>> C.__dict__['f']
    <classmethod object at 0x107d00810>
    >>> C.__dict__['f'].__get__(None, C)
    <bound method type.f of <class '__main__.C'>>
    >>> C.f
    <bound method type.f of <class '__main__.C'>>
    

    它是 __get__ 方法,当您尝试访问 C.f 属性

    函数本身也是描述符;一 分类法 绕过函数的 .__get__ 方法提供对类的绑定,而不是对实例的常规绑定。

    请参见 descriptor HOWTO 了解描述符是什么,以及 分类法 对象工作。

    要查看方法本身返回的内容,只需在类或实例上调用它:

    >>> class C:
    ...     @classmethod
    ...     def f(*args, **kw):
    ...         return args, kw
    ...     def regular(*args, **kw):
    ...         return args, kw
    ... 
    >>> C.f()
    ((<class '__main__.C'>,), {})
    >>> C().f()
    ((<class '__main__.C'>,), {})
    >>> C.regular()
    ((), {})
    >>> C().regular()
    ((<__main__.C object at 0x1085b0790>,), {})
    

    与往常不同 self 实例对象时,该方法被传递给该类的引用。对于这两个 C.f() 调用(直接在类上)和 C().f() (在 C ),第一个参数 f() C 它本身

    将此与 C.regular() 方法这是一个普通的方法,当直接在类上调用时 C.正则() 在使用 C().regular() 传入了第一个参数实例。这是您通常使用的 自己 方法签名中的。

    对于类方法,则第一个参数通常命名为 cls 在声明方法时。

        2
  •  2
  •   jonrsharpe    12 年前

    如果您想拨打 classmethod f 您已在上创建 C ,您应该执行以下操作:

    C.f(...)
    

    classmethod 是decorator函数,它将包装传递给它的任何内容,并返回 classmethod object :

    >>> classmethod(1)
    <classmethod object at 0x02FA6370>
    

    请注意 分类法 是类本身,称为 cls 按照惯例:

    class C:
        @classmethod
        def f(cls, x, y):
            print("words")
    

    这给出了:

    >>> C.f(1, 2)
    words
    

    或者 return 价值和 print 它在功能之外:

    class C:
        @classmethod
        def f(cls, x, y):
            return "words"
    
    >>> print(C.f(1, 2))
    words
    
        3
  •  1
  •   vijay    9 年前

    当在创建的所有不同对象之间共享值时,classmethod非常有用。

    class Classtest:
        a =10
        @classmethod
        def hi(cls, x):
            cls.a= cls.a+x
            print cls.a
    
    h = Classtest()
    h.hi(10)
    
    b = Classtest()
    b.hi(30)
    
    c = Classtest()
    c.hi(40)
    
    >>> ================================ RESTART     ================================
    >>>  
    20
    50
    90
    

    这里,变量a的值在正在创建的所有不同对象之间共享,而不仅仅限于一个实例

        4
  •  0
  •   Mr. Polywhirl    12 年前

    更改为:

    class C:
        @classmethod
        def f(cls, x, y):
            return 'words'
    

    与第一个参数是 self 引用,类方法接收 class 作为隐式第一参数,就像实例方法接收实例一样。

    此外,您需要返回一个值来打印它。