首页 > 技术文章 > Python中面向对象的基本理论(二)

shealee 2021-09-27 17:02 原文

Python中面向对象的基本理论(二)

 

 

属性相关补充

私有化属性

通俗理解:访问范围大的属性限制成访问范围小的(类的内部的)属性

私有化属性的意义:保证数据的安全性

怎么做?

  1. 并没有真正的私有化,而是使用在变量前添加下划线进行伪私有。(适用于类属性和实例属性)
    1. 一个下划线:受保护的属性
    2. 两个下划线:私有属性
       

      类的内部

      子类的内部

      模块内其他位置访问

      跨模块访问

      共有属性

      可以访问

      可以访问

      可以访问

      可以访问

      受保护的属性

      可以访问

      可以访问

      可以访问,但是会警告

      不能访问(警告/报错)

      私有属性

      可以访问

      不能访问

      不能访问

      不能访问

私有化属性的实现机制:名字重整(Name Mangling)私有化之后,名字被重新修改了。(防止被外界调用,防止被子类中同名属性替代)(名字重整是由解释器自动完成的)

私有化属性的应用场景:数据保护;数据过滤(结合其他的方法完成)

只读属性

概念:一个属性(一般指实例属性),只能读取,不能写入

应用场景:有些属性,只限在内部根据不同场景进行修改,对外界来说,不能修改,只能读取。

            (如:电脑类的网速属性,网络状态属性)

怎么设置?:    方案一:先私有化-->既不能读,也不能写;然后部分公开

问题:读取属性的操作方式发生了变化,而且尝试给这个只读属性赋值时,可能会新建一个__age

                装饰器@property解决了以上两个问题:(视频50-53)

                
                @property 将一些属性的操作方法,关联到某一个属性中

                P1 = Person( )

                print(P1.age)

                à直接输出18

方案二:

 

内置特殊属性

 

方法相关补充

私有化方法:和属性一样,def __run( )

内置特殊方法:

Class Person:

    def __init__(self, n , a):

        self.name = n

        self.age = a

def __str__(self):

        return "这个人的姓名是%s,年龄是%s"%(self.name , self.age)

P1 = Person("sz", 18)

print(P1)             #直接print会默认调用__str__方法的返回值

P2 = Person("zhangsan", 19)

print(P2)

运行结果如下:

 

如果定义了这个方法,要获取这个类型的本质信息(地址信息等),那么可以调用__repr__方法:

print(repr(P1))

我们可以重新定义__repr__方法来重新编辑调试代码会用到的调试信息。

__str__方法是面向用户的说明

__repr__方法是面向代码工程师的说明,类型,内存

当一个类中同时定义了以上两种方法时,print(P1)会优先打印__str__中的内容。

当一个类中只定义了__repr__方法时,print会优先打印__repr__中的内容。

当在交互界面调用时,情况如下:

 

__call__方法:

使得"对象"具备当作函数,具备被调用的能力。

Class Person:

    pass

p = Person()

p() #不能被调用

Class Person:

def __call__(self, *args , **kwargs):

        print("xxx")

    pass

p = Person()

p()

用法:

(不包含铅笔部分)

 

索引操作

class Person:

    def __init__ (self ):

        self.cache = {}

    def __setitem__ (self , key , value ):

        self.cache[key] = value

    def __getitem__ (self , key ):

        return self.cache[key]

    def __delitem__ (self , key):

        del self.cache[key]

 

切片操作

https://www.bilibili.com/video/BV1A4411v7b2?p=63视频63

 

比较操作(视频64-67)

如果只定义了等于,要判断是不是不等于,这个时候解释器会自动映射到等于的方法,并取反。(同样适用于 > < 等,大于小于运算是调用参数位置,但是并不会对> = 采用叠加操作。定义了>和=并不能推算出>= 。)

这一点可以用装饰器解决(@functools.total_ordering)

 

上下文布尔值,可以根据判定条件生成类被调用时候的布尔值

def __bool__(self):

    XXXXXX

    return false

    eg. return self.age >= 18

 

推荐阅读