欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

在Python中理解self与类方法的递归运用

最编程 2024-02-20 22:16:52
...

一、代码出错了,错在self

在做LeetCode中的爬楼梯问题时,使用递归试了一下,发现总是报错,代码如下

class Solution:
    def climbStairs(self, n):
        """
        :type n: int
        :rtype: int
        """
        if n == 1:
            return 1
        elif n == 2:
            return 2
        else:
            return climbStairs(n-1) + climbStairs(n-2)

错误原因:NameError: name 'climbStairs' is not defined.

查了资料以后,说是在前面加上self,修改一下就好了,只改变最后一行

return self.climbStairs(n-1) + self.climbStairs(n-2)

二、self的作用

为了理解为什么这样修改是有效的,于是查了Python的类中self参数是什么意思。

参考一篇文章让你彻底搞清楚Python中self的含义

文章中比较重要的一句话:

在Python的解释器内部,当我们调用t.prt()时,实际上Python解释Test.prt(t),也就是说把self替换成类的实例

也就是说,在我们调用类方法时,类中的self会替换成类的实例。
在参考的文章中,Test类 的 prt方法 的作用就是输出self。而在产生实例 t 以后,t.prt()的效果就是先把self替换成 t,然后按照方法的功能输出 t 。

三、出错代码加了self以后的效果

首先我们产生一个实例,然后调用实例方法。

Fn = Solution()
Fn.climbStairss(n)

然后根据上述所说,在调用方法Fn.climbStairss(n)时,Python会把类中的self替换成实例 Fn。于是在下面这行修改后的代码我们可以看到效果

return self.climbStairs(n-1) + self.climbStairs(n-2)

这行代码其实就是返回 Fn.climbStairs(n-1) + Fn.climbStairs(n-2)
调用实例Fn中的方法climbStairs。
这才是比较正确的类实例的方法调用。

如果前面没有self,也就是修改前的代码:

return climbStairs(n-1) + climbStairs(n-2)

那么代码返回的是 climbStairs(n-1) + climbStairs(n-2)。类方法总是要在一个实例进行调用,(当然可以直接用类传入实例调用,但不用在意这个),这里直接调用一个方法,单单只是调用一个方法,显然是不合理的,因为在当前域中,是只有Fn跟Solution的name的,没有别的name。所以会显示错误:NameError: name 'climbStairs' is not defined.

综上所述,在调用类方法中,要注意self的运用。不只是递归,在应用到类时,都需要考虑在方法前面加上self。

另外根据参考的文章,可以知道,一旦产生了一个实例,那么self就会一直是传入的那个实例。这样也保证了即使生成多个新的实例,也不会把原来的实例和新的实例弄乱了。这也是 self 的一个好处吧。

另外,LeetCode这道题用应该用动态规划求解,递归会超时。

推荐阅读