问题描述
所以我知道在 python 中创建一个私有"变量的方法:
Foo 类:def __init__(self):self.__private = 'bar'
这有效"但无效,如下所示:
foo = Foo()'__private' in vars(foo) #False'_Foo__private' in vars(foo) #True
现在,我明白这是在 python 中创建私有变量的方式,我喜欢这种方式.它允许您修改名称,以便没有子类意外覆盖它(因为它以类的名称开头),并且没有人会意外使用它.如果您知道自己在做什么,它还可以让您更改私有变量.此外,这是最好的方法,因为真正的私有变量是不可能的.
我也是这么认为的.
最近,我在阅读 PEP 8 时看到了这一行:
我们在这里不使用术语私有",因为在 Python 中没有真正私有的属性(通常没有不必要的工作量).
此引用可在设计继承部分中找到PEP 8.
注意没有一般不必要的工作量"这句话.我现在确信必须有一种方法可以在 python 中获得真正的私有变量.我该怎么做?
我尝试覆盖 __getattribute__
,但问题是无法判断调用是否来自类内部(我知道).
此外,尝试执行此操作时 __dict__
属性很烦人,因为它包含对所有实例变量的引用.
我也想到了元类,但那些似乎和 __getattribute__
有同样的问题.
想法?
注意:我知道在 python 中创建真正私有变量的任何方法永远都不应在生产代码中完成.我只想知道如何做到这一点.
您可以使用 inspect
模块查找调用函数的名称和模块,您可以将其与白名单进行比较.
但是inspect
也有getattr_static
,可以绕过任何__getattribute__
.
在 Python 中没有什么是真正私有的.有一些方法会使访问变得困难,但总有办法绕过这些方法.
唯一的解决方案是在当前的 Python 解释器之外.您可以将外部函数接口用于其他更安全的语言或远程过程调用(例如 xmlrpc)到相同或在子进程中运行的另一个 Python 解释器,甚至是作为具有不同权限的不同用户运行的解释器.私有变量和所有允许访问它的函数将存在于当前解释器之外.那就没办法检查了.
这种权限分离甚至是说明了 Pyro RPC 库的用例.>
So I know the way to make a variable "private" in python like this:
class Foo:
def __init__(self):
self.__private = 'bar'
This "works" and doesn't, as shown below:
foo = Foo()
'__private' in vars(foo) #False
'_Foo__private' in vars(foo) #True
Now, I understand this is the way to make private variables in python and I like this way. It allows you to mangle names so that no subclasses accidentally override this (because it begins with the class's name), and that nobody will accidentally use it. It also gives you the power to change the private variables if you know what you are doing. Also, it is the best way to do it, because truly private variables are impossible.
Or so I thought.
Recently, I was reading PEP 8 and I saw this line:
This quote is found in the Designing for Inheritance section of PEP 8.
Note the phrase "without a generally unnecessary amount of work". I am now sure that there must be a way to get truly private variables in python. How would I do that?
I have tried overriding __getattribute__
, but the problem is that there is no way to tell if the call is coming from inside the class or not (that I am aware of).
Also, the __dict__
attribute is annoying when trying to do this because it holds references to all instance variables.
I also thought of metaclasses, but those seem to have the same problems as __getattribute__
.
Thoughts?
You can use the inspect
module to find the name and module of the calling function, which you could compare against a whitelist.
But inspect
also has getattr_static
, which can bypass any __getattribute__
.
Nothing is truly private in Python. There are ways to make access difficult, but there are always ways around those ways.
The only solution then, is outside of the current Python interpreter. You could use a foreign function interface to some other more secure language or a remote procedure call (e.g. xmlrpc) to the same or to another Python interpreter running in a subprocess, or even one running as a different user with different permissions. The private variable and all the functions allowed to access it will live outside the current interpreter. Then there's no way to inspect it.
This type of privilege separation is even one of the stated use cases for the Pyro RPC library.
这篇关于Python 3 中真正的私有变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!