彻底搞懂Python数据成员和成员方法

一、数据成员(属性)

数据成员可以大致分为两类:属于对象的数据成员和属于类的数据成员。

  • 属于对象的数据成员一般在构造方法__init__()中定义,当然也可以在其他成员方法中定义,在定义和在实例方法中访问数据成员时以self作为前缀,同一个类的不同对象(实例)的数据成员之间互不影响;
  • 属于类的数据成员是该类所有对象共享的,不属于任何一个对象,在定义类时这类数据成员一般不在任何一个成员方法的定义中。

二、成员方法

Python类的成员方法大致可以分为公有方法、私有方法、静态方法、类方法这几种类型。

  • 公有方法、私有方法一般是指属于对象的实例方法,私有方法的名字以两个下划线"__"开始,而抽象方法一般定义在抽象类中并且要求派生类必须重新实现。每个对象都有自己的公有方法和私有方法,在这两类方法中都可以访问属于类和对象的成员。

  • 公有方法通过对象名直接调用“对象名.公有方法(<实参>)”,私有方法不能通过对象名直接调用,只能在其他实例方法中通过前缀self进行调用或在外部通过特殊的形式来调用。

  • 所有实例方法都必须至少有一个名为self的参数,并且必须是方法的第一个形参(如果有多个形参的话),self参数代表当前对象。

  • 在实例方法中访问实例成员时需要以self为前缀,但在外部通过对象名调用对象方法时并不需要传递这个参数。

  • 如果在外部通过类名调用属于对象的公有方法,需要显式为该方法的self参数传递一个对象名,用来明确指定访问哪个对象的成员。

  • 静态方法和类方法都可以通过类名和对象名调用,但不能直接访问属于对象的成员,只能访问属于类的成员。

  • 静态方法和类方法不属于任何实例,不会绑定到任何实例,当然也不依赖于任何实例的状态,与实例方法相比能够减少很多开销。

  • 类方法一般以简写cls作为类方法的第一个参数表示该类自身,在调用类方法时不需要为该参数传递值,静态方法则可以不接收任何参数。

>>> class Root:
    __total = 0
    def __init__(self, v):    #构造方法
        self.__value = v
        Root.__total += 1
    def show(self):           #普通实例方法
        print('self.__value:', self.__value)
        print('Root.__total:', Root.__total)
    @classmethod              #修饰器,声明类方法
    def classShowTotal(cls):  #类方法
        print(cls.__total)
    @staticmethod             #修饰器,声明静态方法
    def staticShowTotal():    #静态方法
        print(Root.__total)        
>>> r = Root(3)
>>> r.classShowTotal()              #通过对象来调用类方法
1
>>> r.staticShowTotal()             #通过对象来调用静态方法
1
>>> r.show()
self.__value: 3
Root.__total: 1
>>> rr = Root(5)
>>> Root.classShowTotal()           #通过类名调用类方法
2
>>> Root.staticShowTotal()          #通过类名调用静态方法
2
>>> Root.show()    #试图通过类名直接调用实例方法,失败
TypeError: unbound method show() must be called with Root instance as first argument (got nothing instead)
>>> Root.show(r)   #但是可以通过这种方法来调用方法并访问实例成员
self.__value: 3
Root.__total: 2
>>> Root.show(rr)  #通过类名调用实例方法时为self参数显式传递对象名
self.__value: 5
Root.__total: 2

 
 

    三、方法属性

    • 使用@porperty装饰器装饰方法,程序中可以把函数“当作”属性访问,从而提供更加友好的访问方式。

    只读属性:

    >>> class Test:
    	    def __init__(self, value):
    		self.__value = value
    	    @property
    	    def value(self):               #只读,无法修改和删除
    		return self.__value
    >>> t = Test(3)
    >>> t.value
    3
    >>> t.value = 5                        #只读属性不允许修改值
    AttributeError: can't set attribute
    >>> t.v=5                              #动态增加新成员
    >>> t.v
    5
    >>> del t.v                            #动态删除成员
    >>> del t.value                        #试图删除对象属性,失败
    AttributeError: can't delete attribute
    >>> t.value
    3
    
     
     

      可读、可写属性:

      >>> class Test:
          def __init__(self, value):
              self.__value = value	
          def __get(self):
              return self.__value
          def __set(self, v):
              self.__value = v
          value = property(__get, __set)
          def show(self):
              print(self.__value)
      >>> t = Test(3)
      >>> t.value      #允许读取属性值
      3
      >>> t.value = 5  #允许修改属性值
      >>> t.value
      5
      >>> t.show()     #属性对应的私有变量也得到了相应的修改
      5
      >>> del t.value  #试图删除属性,失败
      AttributeError: can't delete attribute
      
       
       

        可读、可修改、可删除的属性:

        >>> class Test:
            def __init__(self, value):
                self.__value = value
            def __get(self):
                return self.__value
            def __set(self, v):
                self.__value = v
            def __del(self):
                del self.__value
            value = property(__get, __set, __del)
            def show(self):
                print(self.__value)
        >>> t = Test(3)
        >>> t.show()
        3
        >>> t.value
        3
        >>> t.value = 5
        >>> t.show()
        5
        >>> t.value
        5
        >>> del t.value            #删除属性
        >>> t.value                #对应的私有数据成员已删除
        AttributeError: 'Test' object has no attribute '_Test__value'
        >>> t.show()
        AttributeError: 'Test' object has no attribute '_Test__value'
        >>> t.value = 1            #为对象动态增加属性和对应的私有数据成员
        >>> t.show()
        1
        >>> t.value
        1
        
         
         
          class asd:
              def __init__(self):
                  self.a = [100,200,300]
          
          
          def func(p):
              p.a=10
          
          
          
          n=asd()
          
          print(n.a)
          func(n)
          print(n.a)
          #换成类方法也一样
          
          class asd:
              def __init__(self):
                  self.a = [100,200,300]
          
          class YOLOv3:
              def __init__(self):
                  self.num_classes = [1,2,3]
          
              def func(self,p):
                  self.num_classes = 100
                  p.a=10
          
          
          
          
          m=YOLOv3()
          n=asd()
          
          print(m.num_classes)
          m.func(n)
          print(m.num_classes)
          
          class asd:
              def __init__(self):
                  self.a = [100,200,300]
          
          
          def func(p):
              p=10
              p.append(1)
          
              return p
              #或者不返回
          
          
          n=asd()
          
          print(n.a)
          m=func(n)
          print(n.a)
          print(m)
          m.append(2)
          print(n.a)
          print(m)
          
          class asd:
              def __init__(self):
                  self.a = [100,200,300]
          
          
          def func(p):
              #p=10
              p.append(1)
          
          
          
          
          n=asd()
          
          print(n.a)
          func(n)
          print(n.a)
          
          
          class YOLOv3:
              def __init__(self):
                  self.num_classes = 12
          
              def func(p):
                  
                  p=p+1
          
          m=YOLOv3()
          
          print(m.num_classes)
          
          
          m.func()
          print(m.num_classes)
          

          一定要充分理解python设计思想,同时遵守一些设计准则,保证可读性,理解计算机系统中内存与运算,达到python之禅的境界。

          参考:

          https://blog.csdn.net/zag666/article/details/105209782
          https://www.cnblogs.com/xianranzhang/p/10683124.html
          https://www.cnblogs.com/chxb/p/11220366.html

          • 24
            点赞
          • 49
            收藏
            觉得还不错? 一键收藏
          • 0
            评论
          Python面向对象编程(Object-Oriented Programming,简称OOP)是一种程序设计方法,它将数据和操作数据方法组合成对象,通过定义类(class)来创建对象。下面是一些概念和原则,可以帮助你更好地理解Python面向对象编程。 1. 类和对象: - 类是一种抽象的数据类型,它定义了对象的属性和方法。 - 对象是类的实例,它具有类定义的属性和方法。 2. 属性和方法: - 属性是对象的数据,可以是整数、字符串、列表等。 - 方法是对象的行为,可以是函数或过程。 3. 封装: - 封装是将数据和对数据的操作封装在一起,以创建一个独立的实体。 - 使用类来封装数据方法,可以隐藏实现细节,提高代码的可读性和可维护性。 4. 继承: - 继承是一种机制,允许一个类继承另一个类的属性和方法。 - 子类可以重用父类的代码,并且可以添加新的属性和方法。 5. 多态: - 多态是指同一个方法可以在不同的类中具有不同的实现方式。 - 多态可以提高代码的灵活性和可扩展性。 下面是一个简单的例子,展示了如何定义一个类、创建对象并调用对象的方法: ```python class Person: def __init__(self, name, age): self.name = name self.age = age def say_hello(self): print(f"Hello, my name is {self.name} and I'm {self.age} years old.") # 创建对象 person = Person("Alice", 25) # 调用对象的方法 person.say_hello() ``` 这个例子定义了一个名为`Person`的类,它有两个属性(`name`和`age`)和一个方法(`say_hello`)。我们通过`Person`类创建了一个名为`person`的对象,并调用了它的`say_hello`方法。 希望这个简单的例子能帮助你更好地理解Python面向对象编程。如果你有其他问题,请随时提问。
          评论
          添加红包

          请填写红包祝福语或标题

          红包个数最小为10个

          红包金额最低5元

          当前余额3.43前往充值 >
          需支付:10.00
          成就一亿技术人!
          领取后你会自动成为博主和红包主的粉丝 规则
          hope_wisdom
          发出的红包
          实付
          使用余额支付
          点击重新获取
          扫码支付
          钱包余额 0

          抵扣说明:

          1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
          2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

          余额充值