该模块支持在自定义对象内部轻松添加私有属性,这些属性在类定义之外完全不可访问,如C++“私有”子句。
private-attrs的Python项目详细描述
私人属性
这个由单个模块组成的小库提供了对really private attributes轻松添加的支持 内部类,这些类从类定义之外完全不可访问,^ {STR 1 } $,如C++私有子句< /强>。在
目录
安装
使用包管理器pip安装private attrs。在
pip3 install private-attrs
使用
这是一个关于自定义类如何使用私有属性的简单模式。在
^{pr2}$如您所见,我们首先需要在函数中定义类。在该类之外,但在函数范围内,我们
实例化一个PrivateAttrs
对象。在
现在,在MyClass
中,如果我们计划拥有私有实例属性,而不仅仅是静态属性,那么必须
在__init__()
方法中,通过调用register_instance()
函数注册实例。在
最后,我们返回MyClass
,并重写函数定义。在
一个简单的例子
现在让我们深入到一个更完整的例子:
fromprivate_attrsimportPrivateAttrsdefPerson():p=PrivateAttrs()classPerson:def__init__(self,name,social_security_number):p.register_instance(self)self.name=namep.ssn=social_security_number@propertydefssn(self):returnp.ssndef__eq__(self,other):returnself.ssn==other.ssndef__hash__(self):returnhash(self.ssn)def__str__(self):returnf"{self.name} - {self.ssn}"def__del__(self):p.delete(self)Person.__qualname__='Person'returnPersonPerson=Person()
虽然一个人可以改变他们的名字,姓氏,甚至他们的性别,这真的不太可能(不是说不可能) 更改他们的社会保险号码(SSN)。在
这就是为什么我们将SSN存储为一个私有属性,安全,不可修改,我们可以依赖它来比较两个人是否 是同一个人。在
proxy=True的示例
如果我们使用Python multiprocessing
库,并且我们希望创建一个具有私有属性的类
可从不同的运行进程访问和修改(我们已经知道,与线程不同,进程不共享
内存空间),我们需要用参数proxy = True
实例化PrivateAttrs
对象。在
我们来看一个例子:
fromprivate_attrsimportPrivateAttrsdefPerson():p=PrivateAttrs(proxy=True)classPerson:def__init__(self,name,social_security_number):p.register_instance(self)self.name=namep.cell_phones=p.manager.list()p.ssn=social_security_number@propertydefssn(self):returnp.ssn@propertydefcell_phones(self):returntuple(p.cell_phones)defadd_cell_phone(self,phone):p.cell_phones.append(phone)def__str__(self):returnf"{self.name} - {self.ssn} - {self.cell_phones}"def__del__(self):p.delete(self)def__getstate__(self):state=dict(self.__dict__)state['private']=p.getstate(self)returnstatedef__setstate__(self,state):private=state.pop('private')p.setstate(private,self)self.__dict__=statePerson.__qualname__='Person'returnPersonPerson=Person()
通过这样做,我们存储的所有私有属性将自动在所有进程中可用,并且您可以修改 从任何人那里。在
请特别注意需要使用Manager
类实例化的特定属性,例如
列表或词典。幸运的是,在PrivateAttrs
类中有一个附加的manager对象,可以简化
程序员。在
还要注意,需要定义__getstate__()
和__setstate__()
魔术方法,这样类就可以
在进程之间共享时,使用其所有私有属性正确序列化和反序列化。在
您应该知道,按照我们编写这个Person
类的方式,其他进程不可能修改public
name
属性,并使该更改对其余部分可见。这是因为此属性尚未用实例化
Manager.Value()
或在Manager.Namespace()
或类似的内部。在
如果您不想使用上述方法存储共享的简单属性,比如str
或
int
将使它们私有化,然后为每个对象生成一个getter(@property
)和一个setter。所以是前者
Person
类如下所示:
classPerson:def__init__(self,name,social_security_number):p.register_instance(self)p.name=namep.cell_phones=p.manager.list()p.ssn=social_security_number@propertydefname(self):returnp.name@name.setterdefname(self,name):p.name=name@propertydefssn(self):returnp.ssn@propertydefcell_phones(self):returntuple(p.cell_phones)defadd_cell_phone(self,phone):p.cell_phones.append(phone)def__str__(self):returnf"{self.name} - {self.ssn} - {self.cell_phones}"def__del__(self):p.delete(self)def__getstate__(self):state=dict(self.__dict__)state['private']=p.getstate(self)returnstatedef__setstate__(self,state):private=state.pop('private',self)p.setstate(private)self.__dict__=state
贡献
欢迎拉取请求。对于重大变化,请先打开一个问题,讨论您希望更改的内容。在
许可证
此库是根据 GNU General Public License v3 or later (GPLv3+)
- 项目
标签: