Python面向对象编程:关于类的方法中属性是否加前缀self的问题

问题的缘起

今天完成了LeetCode首秀(而且是用刚学不久的python做的),心情挺激动的,毕竟之前只涉猎了竞赛OJ,没有在应用型平台上刷过题,不妨定一个小目标,今年拿到力扣全家桶!!!

今天的每日一题对python非常友好,有关数组索引查找,原题如下:

给定一个整数类型的数组 nums,请编写一个能够返回数组 “中心索引” 的方法。
我们是这样定义数组 中心索引 的:数组中心索引的左侧所有元素相加的和等于右侧所有元素相加的和。
如果数组不存在中心索引,那么我们应该返回 -1。如果数组有多个中心索引,那么我们应该返回最靠近左边的那一个。

输入:
nums = [1, 7, 3, 6, 5, 6]
输出:3
解释:
索引 3 (值为6) 的左侧数之和 (1 + 7 + 3 = 11),与右侧数之和 (5 + 6 = 11) 相等。
同时, 3 也是第一个符合要求的中心索引。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-pivot-index

附上我(蒟蒻)的代码:
值得注意的一点是,需要特判首尾的情况,因为单边没有元素记其和为零

class Solution:
    def pivotIndex(self, nums: List[int]) -> int:
        self.before = 0
        self.after = sum(nums[1:])
        self.flag = 0
        if len(nums) == 0:
            self.flag = 0
        elif self.before == self.after:
            self.flag = 1
            self.ans = 0
        else:
            for i in range(len(nums)-1):
                self.before += nums[i]
                self.after -= nums[i+1]
                if self.before == self.after:
                    self.ans = i+1
                    self.flag = 1
                    break
        if self.flag == 0:
            return -1
        else:
            return self.ans

然而码完后我发现了一个问题:代码中出现了太多的self以至于看上去非常不美观,而且在评论区中我发现了不加self的写法

class Solution:
    def pivotIndex(self, nums: List[int]) -> int:
        a=sum(nums[:0])
        b=sum(nums[1:])
        for i in range(0,len(nums)-1):
            if a==b:
                return i
            a+=nums[i]
            b-=nums[i+1]
        if a==b:
            return len(nums)-1
        return -1

暂且不论对错,self存在的必要性确实值得怀疑

问题的解决

解决这个问题,首先需要明白self存在的意义。

self代表的是实例对象,因此带有self前缀的属性都是实例属性,换言之,在类中出现的所有的带有前缀self的属性都在描述实例对象的特征,同一个带有self的属性在实例对象面前完全等价,用一个不太恰当的比喻,事实上就相当于类中实例对象的一种“全局变量”

那么如果去掉self呢?

此时的属性就只能在类的某个方法中被调用,也就如同“局部变量”一样

下面再回到问题本身,显然,self存在与否确实不重要,因为Solution类下只有一个方法成员——pivotIndex,也根本不会出现类中不同方法下属性相互调用的情景

举几个栗子:上面的代码片中a,b只能在方法pivotIndex中使用,既不能从其他方法中调用,也不能在类外调用

class test:
    def __init__(self):
        a = 1
        self.a = 1
    def c(self):
        print(a)    # EEROR:不能由其他方法调用
        print(self.a)
kk = test()
kk.c()
print(test.a)       # ERROR:不能在类外由类调用
print(kk.a)         # ERROR:不能在类外由实例调用

(我们这里把“变量”与“属性”这两个名词一概而论,今后如发现不妥会回来修改,此外部分参考书上指出,上面的代码片中用“调用”一词是不严谨的,欢迎巨佬们在评论区指出原因)

问题的反思

大一上学期学院预置了《程序设计》这门课程,主要学习了C语言的基本语法,甚至连深一点的算法跟数据结构都没有涉及。C语言中对于面向对象编程这一概念并不完善,例如结构体只能支持复杂的数据结构,却不支持算法方法,因而在python当中去理解这一概念的时候会有不小的困难。深入理解类的组成,剖析三大特性——封装性、继承性和多态性,才能更灵活地掌握这门语言。

(第一次写博客,笔者水平有限,请巨佬们见谅啦)

下一篇博客预告:Python中赋值操作与深浅拷贝的秘密

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

放牧星辰dmc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值