Eb9*_*207 8 python scope private
所以我知道在python中创建变量"private"的方法如下:
class Foo:
def __init__(self):
self.__private = 'bar'
Run Code Online (Sandbox Code Playgroud)
这"有效",但没有,如下所示:
foo = Foo()
'__private' in vars(foo) #False
'_Foo__private' in vars(foo) #True
Run Code Online (Sandbox Code Playgroud)
现在,我明白这是在python中创建私有变量的方法,我喜欢这种方式.它可以让你裂伤名,使无意外子类覆盖此(因为它和类的名称开头),而没有人会不小心使用它.如果您知道自己在做什么,它还可以让您更改私有变量.此外,这是最好的方法,因为真正的私有变量是不可能的.
或者我想.
最近,我正在阅读PEP 8,我看到了这一行:
我们在这里不使用术语"私有",因为在Python中没有属性是真正私有的(没有通常不必要的工作量).
该引用可在PEP 8的Designing for Inheritance部分中找到.
注意短语"没有通常不必要的工作量".我现在确定必须有一种方法可以在python中获得真正的私有变量.我该怎么办?
我试过覆盖__getattribute__,但问题是无法判断呼叫是否来自类内部(我知道).
此外,该__dict__属性在尝试执行此操作时很烦人,因为它包含对所有实例变量的引用.
我也想过元类,但那些似乎有同样的问题__getattribute__.
思考?
注意: 我知道在python中创建真正的私有变量的任何方法都不应该在高效的代码中完成.我只是想知道它是如何能做到.
我尝试过重写getattribute,但问题是无法判断调用是否来自类内部(我知道)。
您可以使用该inspect模块查找调用函数的名称和模块,您可以将其与白名单进行比较。
而且inspect还有getattr_static,可以绕过任何__getattribute__。
Python 中没有什么是真正私有的。有一些方法可以让访问变得困难,但总有办法绕过这些方法。
那么唯一的解决方案是在当前的 Python 解释器之外。您可以使用其他更安全的语言的外部函数接口,或者对同一个或子进程中运行的另一个Python解释器进行远程过程调用(例如xmlrpc),甚至可以以具有不同权限的不同用户身份运行。私有变量和所有允许访问它的函数将位于当前解释器之外。那么就没办法检查了。
这种类型的权限分离甚至是Pyro RPC 库的指定用例之一。
通过使用闭包而不是属性,您无需花哨的检查即可获得几乎相同的效果。
class Foo:
def __init__(self):
private = 'bar'
def print_private():
print(private)
self.print_private = print_private
foo = Foo()
foo.print_private() # works
foo.private # kaboom
Run Code Online (Sandbox Code Playgroud)
当然,inspect也可以查看闭包。
| 归档时间: |
|
| 查看次数: |
626 次 |
| 最近记录: |