彻底搞懂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装饰器装饰方法,程序中可以把函数“当作”属性访问,从而提供更加友好的访问方式。

只读属性:

扫描二维码关注公众号,回复: 10323075 查看本文章
>>> 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
发布了115 篇原创文章 · 获赞 445 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/zag666/article/details/105209782