这几天本菜鸟在学习数据结构与算法,学习数据结构与算法免不了要手动实现这些数据结构与算法。在用类定义这些对象的时候,发现老是出现带有 _ ,__ 和__xx__ 的函数,一开始也没怎么在意,想着这些也学过,但是今天仔细思考一下这些用法与区别,才发现已经忘的七七八八了,就这样好奇心逼着我去找出他们的区别。阅读了几篇博客之后,本菜鸟知道了这三兄弟的区别。
1. "_" 单下划线
Python中是不存在真正的私有方法的,但是为了实现类似于c++中的私有方法,于是就在类的方法或者属性前加一个“_”,意味着该方法或者属性就不应该被调用了。
class A(object):
def _test(self):
print("这个函数不应该通过_tset调用,而应该通过test调用")
def test(self):
return self._test()
a = A()
a._test()
a.test()
复制代码
结果
这个函数不应该通过_tset调用,而应该通过test调用
这个函数不应该通过_tset调用,而应该通过test调用
复制代码
由此可得,这个方法是能被调用的,但出于某种约定,我们是一般不去调用的。
2. “__” 双下划线
双下划线表示的是私有类型的变量,既然是私有了,那肯定就不允许子类访问了,只允许这个类(self)自身访问。
class A(object):
def __test(self):
print("I am test in A")
def test(self):
return self.__test()
a = A()
a.test()
复制代码
结果:
I am test in A
复制代码
返回的结果是我们预料之中的。
接着,我们给A添加一个子类,并重新定义它的__test()方法。
class B(A):
def __test(self):
print("I am test in B")
b = B()
b.test()
复制代码
现在,结果是这样的:
I am test in A
复制代码
可见,子类B重新定义之后的__test()返回的依然是A类中的__method(),由此我们可以知道以“__"开头的方法是不能被重写的,只允许在内部使用
"__ xx __" 前后双下划线
这种方法被称为magic methods(魔术方法),一般是系统定义名字,类似于__init__(),一般是给Python调用的。
class WrongMethod(object):
def __init__(self, n):
self.n = n
def __add__(self, other):
return self.n - other
def __sub__(self, other):
return self.n + other
def __str__(self):
return str(self.n)
num = WrongMethod(20)
print("num = ", num)
print("num + 10 = ", num + 10)
print("num - 10 = ", num - 10)
复制代码
结果
num = 20
num + 10 = 10
num - 10 = 30
复制代码
上面的例子就能比较好的提现出来,"__ xx __" 这种方法一般是Python调用的。
结论
- ”_“ 是私有的,一般不应该被调用
- ”__“ 是为了避免子类重写某个函数而使用的
- ”__ xx __“ 一般是用于Python调用