暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Python 基础知识整理 - 类(5)

数据库杂货铺 2021-12-29
288

私有变量

 

Python 中不存在只能从对象内部访问的“私有”实例变量。但是,大多数 Python 代码都遵循一种约定:带有下划线前缀的名称(例如 _spam)应被视为 API 的非公共部分(无论是函数、方法还是数据成员)。应将其视为实施细节,将来如有变更,恕不另行通知。

 

由于类私有成员有一个有效的使用场景(避免名称与子类定义的名称发生冲突),因此 Python 对这种名称改写(name mangling)的机制有简单的支持。格式为 __spam 的任何标识符(至少两个前导下划线,后面最多一个下划线)替换为 _classname__spam,其中 classname 是当前类名(去除前导下划线)。只要标识符出现在类的定义中,就不必考虑标识符的语法位置。

 

名称改写有助于让子类重写方法,而不破坏类内方法调用。例如:

 

class Mapping:
def __init__(self, iterable):
self.items_list = []
self.__update(iterable)


def update(self, iterable):
for item in iterable:
self.items_list.append(item)


__update = update # 原 update() 方法的私有拷贝


class MappingSubclass(Mapping):


def update(self, keys, values):
# 为 update() 提供新签名
# 但是并不破坏 __init__()
for item in zip(keys, values):
self.items_list.append(item)
复制

 

即使 MappingSubclass 引入了一个 __update 标识符,上面的示例也会起作用,因为它在 Mapping 类中被替换为 _Mapping__update,在 MappingSubclass 类中被替换为 _MappingSubclass__update

 

请注意,更改规则的设计主要是为了避免意外;仍然可以访问或修改被视为私有的变量。甚至在特殊情况下很有用,例如在调试器中。

 

注意,传递给 exec() eval() 的代码不认为调用类的类名称是当前类;这与 global 语句的效果类似。同样的限制也适用于 getattr()setattr() delattr(),以及直接引用 __dict__

 

杂项

 

有时,使用类似于 Pascal 的 “record” 或 C 的 “struct” 数据类型,将几个命名的数据项捆绑在一起,是很有用的。空类定义就可以很好地做到这点:

 

class Employee:
pass


fly = Employee() # 创建空 employee


# 填充字段
fly.name = '张飞'
fly.dept = '督察队'
fly.salary = 100000
复制

 

一段需要特定抽象数据类型的 Python 代码通常可以传递一个类来模拟该数据类型的方法。例如,如果有一个函数格式化文件对象中的某些数据,则可以使用 read() readline() 方法定义一个类,这些方法从字符串缓冲区获取数据,并将其作为参数传递。

 

实例方法对象也有属性:m.__self__ 是方法 m() 的实例对象,m.__func__ 是与方法对应的函数对象。

 

 

 

 

 

官方文档:

https://docs.python.org/3.9/tutorial/classes.html


文章转载自数据库杂货铺,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论