Python中,_和xx之间的区别
<time datetime="2010-09-16" pubdate="" style="margin: 0px; padding: 0px;">2010年9月16日</time>
</header>
在学习Python时,很多人并没有真正理解为什么在方法的开头这么强调,有时甚至在结尾这么强调__this__
!我已经被解释了很多次了,是时候进行记录了。
一开始强调
Python没有真正的私有方法,因此在方法或属性的开头加下划线表示您不应访问此方法,因为它不是API的一部分。使用属性时非常常见:
class BaseForm(StrAndUnicode):
...
def _get_errors(self):
"Returns an ErrorDict for the data provided for the form"
if self._errors is None:
self.full_clean()
return self._errors
errors = property(_get_errors)
此摘录摘自django源代码(django / forms / forms.py)。这意味着它errors
是一个属性,并且是API的一部分,但是该属性调用的方法_get_errors
是“私有”的,因此您不应访问它。
开头有两个下划线
这引起很多混乱。它不应用于将方法标记为私有,这里的目的是避免您的方法被子类覆盖。让我们来看一个例子:
class A(object):
def __method(self):
print "I'm a method in A"
def method(self):
self.__method()
a = A()
a.method()
这里的输出是
$ python example.py
I'm a method in A
符合我们的预期。现在让我们子类化A
和自定义__method
class B(A):
def __method(self):
print "I'm a method in B"
b = B()
b.method()
现在的输出是...
$ python example.py
I'm a method in A
如您所见,A.method()
没有B.__method()
像我们预期的那样打电话。实际上,这是的正确行为__
。因此,当您创建一个从头开始的方法时,__
就是说您不想让任何人重写它,只需从自己的类内部即可访问它。
python是怎么做的?很简单,它只是重命名方法。看一看:
a = A()
a._A__method() # never use this!! please!
$ python example.py
I'm a method in A
a.__method()
如我所说,如果您尝试访问它也不起作用,那么__method
只能在类本身内部进行访问。
开头和结尾有两个下划线
当您看到类似的方法时__this__
,规则很简单:不要调用它。为什么?因为这意味着它是python调用的方法,而不是您。看一看:
>>> name = "igor"
>>> name.__len__()
4
>>> len(name)
4
>>> number = 10
>>> number.__add__(20)
30
>>> number + 20
30
总是有一个运算符或本机函数来调用这些魔术方法。这里的想法是让您能够重写自己类中的运算符。有时,在特定情况下,这只是python的一个钩子调用。__init__()
例如,在创建对象时会调用,以便您可以对其进行初始化。__new__()
被调用来构建实例,依此类推...
这是一个例子:
class CrazyNumber(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 = CrazyNumber(10)
print num # 10
print num + 5 # 5
print num - 20 # 30
另一个例子:
class Room(object):
def __init__(self):
self.people = []
def add(self, person):
self.people.append(person)
def __len__(self):
return len(self.people)
room = Room()
room.add("Igor")
print len(room) # 1
该文件涵盖了所有这些特殊的方法。
结论
使用_one_underline
你方法标记为不API的一部分。使用__two_underlines__
当你创建对象看起来像本地Python对象,或者您wan't自定义在特定情况下的行为。并且不要使用__just_to_underlines
,除非您真的知道自己在做什么!
</article>
相关文章
- 2016年10月21日 » 在Python中动态生成测试函数
- 2016年10月19日 » 使用HTTPie发布字符串
- 2013年3月17日 » 测试无限循环
网友评论