python - 'exec' 不适用于私有(private)方法 Python

标签 python class exec private

我知道你们中的大多数人都认为不应该使用 exec,但我有一些问题。

这是一个最小的例子,它有效:

class A:
    def __init__(self):
        exec('self.a = self.funct()')
    def funct(self):
        return 1
    def ret(self):
        return self.a
> obj = A()
> obj.ret()
1

但是,当我这样做时:

class A:
    def __init__(self):
        exec('self.a = self.__funct()')
    def __funct(self):
        return 1
    def ret(self):
        return self.a
> obj = A()
AttributeError: 'A' has no attribute '__funct'

有人知道为什么会出现这种差异吗?

最佳答案

__name 名称是类私有(private);这些名称在编译时带有另一个下划线和类名作为前缀。目的是防止名称与子类中使用的名称发生意外冲突。这些名称​​不对于外部调用者来说是私有(private)的。

引用Reserved classes of identifiers section :

__*
Class-private names. Names in this category, when used within the context of a class definition, are re-written to use a mangled form to help avoid name clashes between “private” attributes of base and derived classes.

Identifiers (Names) section :

Private name mangling: When an identifier that textually occurs in a class definition begins with two or more underscore characters and does not end in two or more underscores, it is considered a private name of that class. Private names are transformed to a longer form before code is generated for them. The transformation inserts the class name, with leading underscores removed and a single underscore inserted, in front of the name. For example, the identifier __spam occurring in a class named Ham will be transformed to _Ham__spam. This transformation is independent of the syntactical context in which the identifier is used.

在您的情况下发生的情况是 exec() 推迟编译,有效地单独编译该调用。类上下文消失了,因此不会发生任何损坏。

因此,您需要手动应用自动前缀:

exec('self.a = self._A__funct()')

如果您使用的是 Python 3,则可以使用 __class__ 闭包 normally available for the super() function访问当前方法定义的类名:

exec('self.a = self._{0.__name__}__funct()'.format(__class__))

现在,除非您实际上计划在第三方代码中广泛子类化您的类,而不必担心与内部实现细节意外冲突,否则您根本不应该使用双下划线名称。坚持使用单下划线名称。

关于python - 'exec' 不适用于私有(private)方法 Python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41637600/

相关文章:

python - 如何从 scikit-learn 中的 TfidfTransformer 获得最匹配的特征名称?

php - 在 PHP 类中将 var 从一个函数共享到另一函数

php - 从子类 php 和 parent 关键字访问 parents 变量?

c++ - 编写 Shell - 使用 system() 或 exec() 来运行命令?

python - 随机森林权重错误无属性复制

python - 什么在第五行之后切片行

c++ - 使用此指针时 C++ 析构函数错误的原因?

python - 第二个同时 'for loop' 执行中断第一个

sql-server-2008 - T-SQL(MS SQL 2008),不带 'EXEC'或 'EXECUTE'词的执行过程

python - 使用 python 的 pysftp 包,我在尝试上传文件时收到 OSError