【问题标题】:Difference between Class Attributes, Instance Attributes, and Instance Methods in PythonPython中类属性、实例属性和实例方法的区别
【发布时间】:2016-02-20 07:06:01
【问题描述】:

我知道以前有人问过类似的问题,但每个网站似乎对这些事情的定义不同,我正在尝试遵循官方文档: 据我所知:
- 类属性是class Classname: 代码块中列出的所有内容,包括__init__ 函数上方的变量声明、静态方法、类方法和涉及self 实例的方法
更多信息链接:https://docs.python.org/2/tutorial/classes.html#class-objects
- 实例属性是:1.)class Classname: 代码块中列出的每个函数,所以除了__init__ 函数上方的变量声明和 2.)当我们使用 instance.attr 并将其设置为相等时的数据属性达到一定的价值
更多信息链接:https://docs.python.org/2/tutorial/classes.html#instance-objects

假设我上面写的一切都是正确的,我会说实例方法是class Classname:代码块中的任何函数,因为我们可以将每个方法应用于实例对象,或者它可能只是涉及self的函数

我不确定我理解错了什么,但是 python 文档的术语与我见过的其他网站完全不同。任何帮助将不胜感激。谢谢!

【问题讨论】:

    标签: python


    【解决方案1】:

    类属性对于类的所有实例都相同,而实例属性对于每个实例都是特定的。实例属性用于特定于每个实例的数据,并且类属性应该由该类的所有实例使用。

    “实例方法”是一个特定的类属性,它接受类的实例作为第一个属性并假设使用该实例进行操作。

    “类方法”是在类中定义的方法,它接受类作为第一个属性而不是实例(这就是类方法的原因)。

    您可以通过访问A.__dict__轻松查看类属性:

    class A:
       class_attribute = 10
       def class_method(self):
           self.instance_attribute = 'I am instance attribute'
    
    print A.__dict__
    #{'__module__': '__main__', 'class_method': <function class_method at 0x10978ab18>, 'class_attribute': 10, '__doc__': None}
    

    实例属性为A().__dict__:

    a = A()
    a.class_method()
    print a.__dict__
    # {'instance_attribute': 'I am instance attribute'}
    

    一些来自官方python文档和SO的有用链接,我希望不会让你更困惑,让你更清楚地理解......

    【讨论】:

      【解决方案2】:

      要回答这个问题,首先需要考虑一下python是如何查找属性的。我假设您知道实例是什么。作为复习。 . .

      class SomeClass(object):
      
          class_attribute = 'This -- Defined at the class level.'
      
          def __init__(self):
              self.instance_attribute = 'This -- Defined on an instance.'
      
          def method(self):
              pass
      
      instance = SomeClass()
      

      类属性在类级别定义。实例属性在实例级别定义(通常通过self.xyz = ...)。实例属性也可以猴子修补到实例上:

      instance.another_instance_attribute = '...'
      

      请注意,如果实例属性没有“隐藏”它,则可以在实例上查找类属性。

      print(instance.class_attribute)
      

      现在是方法。方法完全是另一种动物。

      SomeClass.method
      

      绝对是类的一个属性。

      instance.method
      

      分类有点棘手。实际上,当python看到该语句时,它实际上执行了以下操作:

      SomeClass.method.__get__(instance, SomeClass)
      

      很奇怪。所以这里发生的是函数是描述符。因为他们有一个__get__ 方法,它被调用并且返回值(在这种情况下)是一个知道self 是什么的新函数。正常的术语是“实例方法”和“绑定方法”。我想有些人可能会认为它是一个实例属性,但是,我不确定这是否完全正确(即使您通过实例访问它)

      【讨论】:

        【解决方案3】:

        您似乎对这些概念有相当不错的理解。很难找到以通用方式解释的信息,尤其是对于像 python 这样广泛使用的语言。我主要会回应您的正确假设,并在此过程中进行一些小调整。

        类属性是将从类中创建的所有对象共有的特征。例如,如果我们要定义一个clock 类,我们会将一个类属性定义为时钟中可能的总小时数。

        class Clock:
            class_hours = 12
        

        它由类的所有实例共享,并且可以被任何实例访问以供参考。

        类实例是我们用来定义从类创建的对象的个人特征的实际数据。再次使用clock Class 示例,这将是我们在一行代码中创建时钟时设置时钟的实际小时(我们也可以引用我们的 Class 属性以确保它在可接受的参数范围内):

        class Clock:
            class_hours = 12
        
            def __init__(self, hours):
                if (hours <= class_hours):
                    self.hours = hours
        

        请记住,在构造函数中使用if 语句不是一个好习惯,但这是为了举例。如果你真的想实现这个例子,你可以使用实例方法来确保小时在定义的范围内。

        实例方法是我们在类中定义的方法,可以操作我们在构造函数中定义的类实例数据。再次回到clock 的例子,我们可以定义一个改变时钟的小时、分钟或秒的方法:

        class Clock:
            class_hours = 12
            class_minutes = 60
            class_seconds = 60
        
            def __init__(self, hours, minutes, seconds):
                self.hours = hours
                self.minutes = minutes
                self.seconds = seconds
        
            def setTime(new_hour, new_minute, new_second):
                self.hours = new_hour
                self.minutes = new_minute
                self.seconds = new_second
        

        这允许我们更改我们已经在代码中某处创建的clock 的实例。例如,调用 clock.setTime(11,49,36) 会将特定的时钟实例设置为 11:49:36。

        我希望这对您有所帮助并且尽可能清晰。如果我含糊不清或掩盖了您不理解的任何术语,请告诉我,以便我更新我的答案,使其尽可能清晰。

        【讨论】:

        • 感谢您的回复!我的主要问题是文档字面上有一行:“根据定义,作为函数对象的类的所有属性都定义了其实例的相应方法。” 类属性的另一部分说类属性是命名空间中的任何内容在类下,包括涉及自我的功能。那么类属性不就是类代码块中的一切,而实例方法不是类代码块中的所有功能吗?我理解您在上面写的内容,但这似乎与网站上的内容大相径庭。
        【解决方案4】:

        类属性- 是类Classname中列出的所有内容:代码块,它可以在任何方法的上方或下方。

        Instance 属性 - 使用 instance.attr 或 self.attr 创建(这里 self 只是实例对象)

        class Base:
          cls_var = "class attribute"
          def __init__(self):
            self.var = "instance attribute"
          def method(self):
            self.var1 = "another instance attribute"
          cls_var1 = "another class attribute"
        

        类属性和实例对象 - 您可以将类对象视为其所有实例对象的父对象。所以实例对象可以访问类对象的属性。但是在类主体下定义的任何东西都只是类属性。

        class Base:
          cls_var = "class attribute"
          def __init__(self):
            self.var = "instance attribute"
        b = Base()
        print b.var                                     # it should print "instance attribute"
        print b.cls_var                                 # it should print "class attribute"
        print Base.cls_var                              # it should print "class attribute"
        b.cls_var = "instance attribute"
        print Base.cls_var                            # it should print "class attribute"
        print b.cls_var                                # it should print "instance attribute"
        

        Instance Method - 由类体内的 def 语句创建的方法,实例方法是一个 Method,其第一个参数将是实例对象(self)。 但是所有实例方法都是类属性,您可以通过实例对象访问它,因为实例是类对象的子对象。

        >>> class Base:
            def ins_method(self):
                pass
        
        
        >>> b = Base()
        >>> Base.__dict__
        {'__module__': '__main__', '__doc__': None, 'ins_method': <function ins_method at 0x01CEE930>}
        >>> b.__dict__
        {}
        

        您可以通过将实例作为第一个参数传递来使用类对象来访问实例方法-

        Base.ins_method(Base())
        

        您可以参考我写的关于同一主题的这两篇文章,其中有图表解释,并将您的查询发给我 - http://www.pythonabc.com/python-class-easy-way-understand-python-class/ http://www.pythonabc.com/instance-method-static-method-and-class-method/

        【讨论】:

          猜你喜欢
          • 2018-04-14
          • 1970-01-01
          • 2010-11-21
          • 2021-12-26
          • 2011-11-24
          • 2011-12-01
          • 2015-09-10
          相关资源
          最近更新 更多