51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 1240|回复: 1
打印 上一主题 下一主题

python _、__和__xx__的区别

[复制链接]
  • TA的每日心情
    奋斗
    2021-8-16 14:04
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]测试小兵

    跳转到指定楼层
    1#
    发表于 2018-4-20 11:54:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    Python中不存在真正的私有方法。为了实现类似于c++中私有方法,可以在类的方法或属性前加一个“_”单下划
    线,意味着该方法或属性不应该去调用,它并不属于API。

    在使用property时,经常出现这个问题:

    复制代码
    1. class BaseForm(StrAndUnicode):
    2.     ...
    3.    
    4.     def _get_errors(self):
    5.         "Returns an ErrorDict for the data provided for the form"
    6.         if self._errors is None:
    7.             self.full_clean()
    8.         return self._errors
    9.    
    10.     errors = property(_get_errors)
    复制代码

    复制代码
    上面的代码片段来自于django源码(django/forms/forms.py)。这里的errors是一个属性,属于API的一部分,
    但是_get_errors是私有的,是不应该访问的,但可以通过errors来访问该错误结果。

    "__"双下划线
    这个双下划线更会造成更多混乱,但它并不是用来标识一个方法或属性是私有的,真正作用是用来避免子
    类覆盖其内容。

    让我们来看一个例子:

    1. class A(object):
    2.     def __method(self):
    3.         print "I'm a method in A"
    4.     def method(self):
    5.         self.__method() a = A() a.method()
    6. 输出是这样的:

    7. $ python example.py
    8. 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
    就像我们看到的一样,B.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。

    "__xx__"前后各双下划线
    当你看到"__this__"的时,就知道不要调用它。为什么?因为它的意思是它是用于Python调用的,如下:

    >>> name = "igor"
    >>> name.__len__() 4
    >>> len(name) 4
    >>> number = 10
    >>> number.__add__(20) 30
    >>> number + 20 30
    “__xx__”经常是操作符或本地函数调用的magic methods。在上面的例子中,提供了一种重写类的操作符
    的功能。

    在特殊的情况下,它只是python调用的hook。例如,__init__()函数是当对象被创建初始化时调用的;__ne
    w__()是用来创建实例。

    复制代码
    1. class CrazyNumber(object):
    2.     def __init__(self, n):
    3.         self.n = n
    4.     def __add__(self, other):
    5.         return self.n - other
    6.     def __sub__(self, other):
    7.         return self.n + other
    8.     def __str__(self):
    9.         return str(self.n)

    10. num = CrazyNumber(10)
    11. print num # 10
    12. print num + 5 # 5
    13. print num - 20 # 30   
    复制代码

    复制代码
    另一个例子

    复制代码
    1. class Room(object):
    2.     def __init__(self):
    3.         self.people = []
    4.     def add(self, person):
    5.         self.people.append(person)
    6.     def __len__(self):
    7.         return len(self.people)

    8. room = Room()
    9. room.add("Igor")
    10. print len(room) # 1
    复制代码

    复制代码
    结论
    使用_one_underline来表示该方法或属性是私有的,不属于API;
    当创建一个用于python调用或一些特殊情况时,使用__two_underline__;
    使用__just_to_underlines,来避免子类的重写!

    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-11-18 00:46 , Processed in 0.064141 second(s), 22 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表