0


python 类内变量和函数 定义重名

结论

在底层实现中,在声明python类时,会按照声明的顺序把变量和函数的指针装到某个容器里,并在调用的时候从头到尾遍历,名字和用法匹配即返回。

事发经过

之前在写python的时候,脑子一抽,写了这样的代码(大致)

classchar_embedding():def__init__(self, size_1, size_2):
        self.char_embedding = nn.Embedding(size_1, size_2)defchar_embedding(self, x):return self.char_embedding(x)

很有趣的一点是这些东西也能跑起来。但是在想用对象调用这个类的函数的时候,总传出一些奇怪的错误,比如给forword函数传参不对啦之类的。

实验验证 & 结论

经过试验我发现,python的类在储存变量以及函数的时候,应该有一个特定的容器按照定义顺序存下他们的指针。我们可以用下面这个简单的例子做演示:

classA():def__init__(self):
        self.A = nn.Embedding(1,1)defA(self, x):return x

这种情况和我上述代码出现了相同的错误,在通过A的实例调用函数A时,实际调用的是

nn.Embedding

这个‘A’。但反之,如果我们换一下变量和函数的定义顺序:

classA():def__init__(self)->None:
        self.nothing_important =1defA(self, x):
        self.A = nn.Embedding(1,1)return x

这种情况下,类内函数A先于类内变量A声明,在想通过实例调用变量A的时候实际得到的是函数A。

有一点需要说明,这个

nn.Embedding

实际上是一个类的实例,其继承自

module

类,有一个需要(且已经)复写的

forward

函数,通过调用

nn.functional.Embedding

这个函数进行的实现。换言之,其使用方法和函数时一样的,用小括号进行传参,所以会产生混淆。如果变量是’真正意义上uncallable的一个东西,那是一定能通过有小括号与否区分开的。

那么综上几点,我们可以推测,底层类的实现应该有一个容器,装着按照声明顺序填充的变量、函数的指针,在类的实例试图调用的时候,会在这个容器中按照从头到尾的顺序进行遍历,遇到名字匹配且用法兼容的项就返回相应的指针(函数)或内容(变量)。

标签: python

本文转载自: https://blog.csdn.net/Petersburg/article/details/120005760
版权归原作者 Petersburg 所有, 如有侵权,请联系我们删除。

“python 类内变量和函数 定义重名”的评论:

还没有评论