Python3 kwarg 以 dunder 开头,在类和 dataclass 生成的私有属性中是不可能的



我对以下行为有点困惑(在Python 3.9中):

class Dunder:
def __init__(self, __a_kwarg="hello"):
self.__a_kwarg = __a_kwarg
print(self.__a_kwarg)
Dunder(__a_kwarg="Hello world")
TypeError: __init__() got an unexpected keyword argument '__a_kwarg'

但是如果我这样做了:

class Dunder:
def __init__(self, __a_kwarg="hello"):
self.__a_kwarg = __a_kwarg
print(self.__a_kwarg)
Dunder("Hello world")
"Hello world"

第一个实参被分配给第一个形参,如预期的那样,一切正常。

使用一个正常的函数也可以正常工作:

def fn(__a_kwarg="hello"):
print(__a_kwarg)
fn(__a_kwarg="Hello world")
"Hello world"

我怀疑它与"dunder"有关。提示私有变量。但是为什么不能用双下划线来处理kwarg呢?

搜索网络,我从MyPy问题/5156中发现了这个问题,但这并没有提供我问题的答案。

我这样做是因为我想让dataclass具有一个具有默认值的私有属性,我的IDE (PyCharm)建议我可以将此参数作为kwarg(这将是伟大的,因为有多个可选参数),但Python说没有。

我的实际代码片段:

@dataclass
class Incident(JsonDumpable):
""" Class representing a single incident"""
id_: Union[incident_id, float]
__timeout_s: int
__response: IncidentResponse = IncidentResponse.NoResponse
active: bool = True

Incident(
loaded_dict["id"],
loaded_dict["timeout_s"],
__response=IncidentResponse.get_enum(loaded_dict["response"]),
active=loaded_dict["active"],
)

或者,我如何在datacclass "中使用kwarg来解决我的"私有参数?问题吗?我已经知道__post_init__是一件事,在那里我可以介绍我的私人"副本",但是我如何摆脱由数据类创建的非私有版本(以PyCharm获得此属性被删除的方式)?

我找到了为什么它不起作用的答案。为什么是这样实现的问题是另一个问题…

import inspect

class Dunder:
def __init__(self, __a_kwarg="hello"):
print(self.__a_kwarg)
print(inspect.signature(Dunder.__init__))
Dunder(_Dunder__a_kwarg="Hello world")
(self, _Dunder__a_kwarg='hello')
Hello world

所以当python以"dunder"开头时,它真的会把kwarg弄乱("hides")

__a_kwarg变为_Dunder__a_kwarg,您可以处理"new";像你习惯的那样。

我引用了文档中的源代码,在这里的相关问题中也提到了。

"作为变量或属性前缀会触发Python的名称混淆功能,即而不是被称为"私有属性";在语言文档中。Python的没有私有属性,它的oo模型是基于"同意成人"的前提:一个单一的";表示该属性不应该被第三方代码篡改。

"__";前缀实现了"私有"的一个非常实用的方面。属性,这是为了避免在大型继承层次结构中的属性名称冲突-不应该被人们使用。"__"方法中参数名称中的前缀在编译时更改-以便类中使用相同名称的其他方法能够访问它,但是类之外的任何内容(例如您的代码试图实例化类并将其作为命名参数传递)都必须手动执行名称混淆以匹配内部创建的内容。它的转换很简单:"_"prefix + class_name + original_name——这样写fn(_Dunder__a_kwarg="Hello world")就可以了——但如果你不尝试这样做,你的生活会更容易。

只使用简单的下划线前缀,"_ "要指定私有属性,您将会很好。

相关内容

最新更新