zoukankan      html  css  js  c++  java
  • python中的下划线

    Difference between _, __ and __xx__ in Python

    许多人在学习python的时候并没有真正理解下划线的意义,下面给出详细的解释。

    One underline in the beginning

    Python doesn't have real private methods, so one underline in the beginning of a method or attribute means you shouldn't access this method, because it's not part of the API. It's very common when using properties:

    Python没有像C++那样的私有域,使用一个下划线开头的方法或属性表示你无法通过对象名或类名访问该方法或属性,即该方法或属性是private的,对外部不可见。

    对于properties同样适用。

    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)
    

    This snippet was taken from django source code (django/forms/forms.py). This means errors is a property, and it's part of the API, but the method this property calls, _get_errors, is "private", so you shouldn't access it.

    Two underlines in the beginning

    This one causes a lot of confusion. It should not be used to mark a method as private, the goal here is to avoid your method to be overridden by a subclass. Let's see an example:

    双下划线开头的方法是为了防止子类重写该方法。

    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
    

    输出没问题,现在看下子类也有同样的__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
    

    as you can see, A.method() didn't call B.__method() as we could expect. Actually this is the correct behavior for __. So when you create a method starting with __ you're saying that you don't want anybody to override it, it will be accessible just from inside the own class.

    How python does it? Simple, it just renames the method. Take a look:

    a = A()
    a._A__method()  # never use this!! please!
    
    $ python example.py
    I'm a method in A
    

    If you try to access a.__method() it won't work either, as I said, __method is just accessible inside the class itself.

    Two underlines in the beginning and in the end

    When you see a method like __this__, the rule is simple: don't call it. Why? Because it means it's a method python calls, not you. Take a look:

    >>> name = "igor"
    >>> name.__len__()
    4
    >>> len(name)
    4
    
    >>> number = 10
    >>> number.__add__(20)
    30
    >>> number + 20
    30
    

    There is always an operator or native function that calls these magic methods. The idea here is to give you the ability to override operators in your own classes. Sometimes it's just a hook python calls in specific situations. __init__(), for example, is called when the object is created so you can initialize it. __new__() is called to build the instance, and so on...

    Here's an example:

    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

    Another example:

    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
    

    The documentation covers all these special methods.

    Conclusion

    Use _one_underline to mark you methods as not part of the API. Use__two_underlines__ when you're creating objects to look like native python objects or you wan't to customize behavior in specific situations. And don't use__just_to_underlines, unless you really know what you're doing!

  • 相关阅读:
    呵呵,今天偶然看到了我最早期的商业网站作品
    轻量级的Ajax解决方案——DynAjax:直接在客户端调用C#类的方法
    RegexDesigner.NET 正则表达式开源工具
    Asp.net页面的生命周期之通俗理解
    我设计的公司网站主页 截图
    没想到裴勇俊留了一头长发。
    一个very好的Javascript ajax库,jQuery!
    JQuery资源收集
    收藏:悟透JavaScript
    VS2008 F5不能调试情况一例
  • 原文地址:https://www.cnblogs.com/chybot/p/4557729.html
Copyright © 2011-2022 走看看