1
  1. 这两个类声明有什么区别?“对象”有什么作用?

    class className(object):
        pass 
    
    class className:
        pass 
    
  2. 为什么我在运行以下代码时会收到此错误:“不接受任何参数(给定 1 个)”

    class Hobbs():
        def represent():
            print "Hobbs represent!"
        represent = classmethod(represent)
    
    Hobbs.represent()   
    
  3. 为什么即使我没有将参数传递给函数,“Foo.class_foo()”也不会出错。

    class Foo(object):
        @staticmethod
        def static_foo():
        print "static method"
        @classmethod
        def class_foo(cls):
            print "Class method. Automatically passed the class: %s" % cls      
    Foo.static_foo()
    Foo.class_foo()
    
  4. 为什么我在运行以下代码时会收到此错误?

    class Foo(object):  
        def static_foo():
            print "static method"
            static_foo = staticmethod(static_foo)
        def class_foo(cls):
                print "Class method. Automatically passed the class: %s" % cls
        class_foo = classmethod(class_foo)  
    Foo.static_foo()
    Foo.class_foo()
    

“TypeError:必须使用 Foo 实例作为第一个参数调用未绑定的方法 static_foo()(什么都没有)”

4

5 回答 5

5
  1. object至少从 Python 2.2 开始,作为新类的基类就已成为惯例,并且被称为“新样式类”——有关更多详细信息,请参阅此问题。旧样式类(即:不继承自 的类object)在 Python 3.0 中被设置为弃用。这些变化的原因有些模糊,与低级类解析和继承模式有关。

  2. 按照惯例,Python 实例方法self作为它们的第一个参数。这个参数是隐式传递的——所以如果你的方法定义不接受self,那么解释器会抱怨你试图调用的方法不接受自动传递给它的参数。这对于类方法完全相同,只是self它们通常不采用 ,而不是采用cls。(只是一个命名约定。)快速修复:

    class Hobbs():
        def represent(cls):
            print "Hobbs represent!"
        represent = classmethod(represent)
    
    Hobbs.represent()   
    
  3. 调用Foo.class_foo()不会导致任何问题,因为class_foo无论何时调用,Python 都会自动将类对象传递给方法。这些方法称为绑定方法——这意味着它们是常规函数,但绑定到类或实例对象。绑定方法自动将它们绑定到的类或实例对象作为它们的第一个参数。

  4. 缩进级别在 Python 中很重要。我已尝试执行您提供的代码示例,但static_foo =class_foo =行都必须在Foo类定义内,而不是在它之下或在其他方法内。正确缩进后,代码运行良好:

    class Foo(object):
        def static_foo():
            print "static method"
        static_foo = staticmethod(static_foo)
        def class_foo(cls):
            print "Class method. Automatically passed the class: %s" % cls
        class_foo = classmethod(class_foo)
    Foo.static_foo()
    Foo.class_foo()
    
于 2012-09-23T01:41:43.407 回答
1
  1. 最后两个是相同的 - 空括号与省略它们相同。第一个继承自内置类object,使其成为“新样式类”。新旧样式类的原因是历史性的,而旧样式只是为了向后兼容而保留——本质上,在 Python 2 中,object如果你不从其他任何东西继承,建议总是从继承,因为一些您将学习的花哨技巧最终依赖于它。如果升级到 Python 3,这将成为默认行为,并且所有三个类声明都是等效的。

  2. Aclassmethod需要采用类似于self- 的第一个参数,当您调用 时Hobbs.represent(),Python 最终Hobbs会作为第一个参数传入。classmethod这是和之间的根本区别staticmethod- aclassmethod接受第一个参数(作为它被调用的类), astaticmethod没有。

  3. 与 2-class 相同的是传递给classmethodin 代替通常的self

  4. 这似乎是一个缩进问题 - 如果它被缩进,您的代码就可以正常工作:

    def static_foo():
        print "static method"
    static_foo = staticmethod(staticfoo)
    

但不像

def static_foo():
    print "static method"
    static_foo = staticmethod(staticfoo)    

因为重新分配的行static_foo需要在类主体中,而不是函数本身的一部分。在后者中,该行在函数运行之前不会执行(这意味着它没有运行,因为函数错误) - 并且它将 a 分配staticmethod给局部变量而不是方法本身。这种类型的错误是最好使用装饰器语法的原因之一:

 class Hobbs:
    @staticmethod
    def static_foo():
         print "static method"

作品。

于 2012-09-23T01:49:42.130 回答
0

您的大多数问题都不是关于面向对象本身,而是 Python 的具体实现。

  1. Python 2.x 经历了一些演变,添加了新功能。所以有两种定义类的方法,产生了“新式类”和“旧式类”。Python 3.x 只有“新样式类”。新型类的基础对象称为object. 如果你从那里继承,你就有了一个新风格的类。它为您提供了一些额外的功能,例如某些装饰器。如果您在 Python 2.x 中有一个简单的(无继承)定义,那么您就有了一个老式类。这是为了向后兼容而存在的。在 Python 3.x 中,您还将获得一个新样式的类(因此从object那里继承是可选的)。

  2. 您已经制作了represent()“类方法”。所以它会在调用时将类对象作为隐式的第一个参数。但那些只适用于新型类。您已尝试将它与旧式类一起使用。所以它不会工作。

  3. Python 自动插入类对象作为类方法的参数零。所以这是正确的模式并且有效。

  4. 该方法不知何故没有进入类方法,可能是因为缩进错误。

于 2012-09-23T01:47:43.587 回答
0
  1. class ClassName(OtherClass): 表示 ClassName 继承自 OtherClass。继承是一个很大的主题,但基本上它意味着 ClassName 至少具有与 OtherClass 相同的功能和字段。

    在 python 中,一切都是对象,因此,所有类都隐式或显式地从对象继承。这么说

    class ClassName():声明是一种旧语法,应避免使用。

    class ClassName:相当于类ClassName(object):

  2. 类方法不是静态方法。它与任何其他实例方法一样,只是它作为参数而不是实例传递给类。

    你的类方法声明是错误的。它应该有一个 cls 参数。

  3. 另一方面,静态方法是在上下文之外调用的方法。这意味着它与任何实例都没有关系。它可以被认为是一个独立的函数,出于语义原因简单地放在一个类中。

    这就是为什么它不需要 self 参数并且永远不会传递给它的原因。

  4. 你有一个缩进错误。这可能是导致错误的原因。

于 2012-09-23T01:48:05.263 回答
0

所有类函数都必须以 self 作为第一个参数

class  A:
   def my_func(self):
        print "In my func"

静态方法是几乎只是命名空间中的一个函数的类(在 python 中很少使用)

类方法是类命名空间中的函数,应该在类本身而不是实例上调用

于 2012-09-23T01:19:28.707 回答