新版博客SEO优化基本完成,新老博客内容正在整合中,保证每篇文章高质量。 SiteMap RSS Github
Python中_xx、__xx、__xx__、xx_的使用
嘉美伯爵   2019年6月14日 20:24   Python   语法   182  

_xx

_xx 方法或属性为类的私有标志, import不能导入,它不属于API,不应该被外部访问到,但是使用__all__可以强制调用,单下划线的属性或方法可以被子类使用

  • property调用私有方法
class Animal:

    def _get_errors(self):
        return "I'm errors info"

    test = property(_get_errors)

a = Animal()
print(a.test)  # I'm errors info
print(dir(a)) # [...,'_get_errors','test']
  • 子类访问父类私有属性
class Animal:

    def __init__(self):
        self._name = "I'm Animal"
        self.age = 18

    def _get_errors(self):
        return "I'm errors info"

    test = property(_get_errors)


class Cat(Animal):
    def print_animal_name(self):
        return self._name + ', name is cat.'

cat = Cat()
print(cat.print_animal_name()) # I'm Animal, name is cat.

__xx

__xx 的作用就是避免子类重写,__xx 的私有变量被Python name mangling技术翻译成 _ClassName__attribute的形式,一旦属性或方法前面加双下划线,就说明该属性或方法只能在本类使用,连子类都不可使用或访问

  • 普通方法重写
class Person:
    def __init__(self, colour):
        self.colour = colour

    def person_colour(self):
        return "I'm {} person from parent class.".format(self.colour)

    def print_person_colour(self):
        print(self.person_colour())

class YellowPerson(Person):

    def person_colour(self):
        return "I'm yellow person from child class."

yellow = YellowPerson('yellow')
yellow.print_person_colour() # I'm yellow person from child class.
print(yellow) # ['_Person__colour',....]
  • 单下划线私有方法重写
class Person:
    def __init__(self, colour):
        self._colour = colour

    def _person_colour(self):
        return "I'm {} person from parent class.".format(self._colour)

    def print_person_colour(self):
        print(self._person_colour())

class YellowPerson(Person):

    def _person_colour(self):
        return "I'm yellow person from child class."

yellow = YellowPerson('yellow')
yellow.print_person_colour() # I'm yellow person from child class.
  • 双下划线私有方法重写
class Person:
    def __init__(self, colour):
        self.__colour = colour

    def __person_colour(self):
        return "I'm {} person from parent class.".format(self.__colour)

    def print_person_colour(self):
        print(self.__person_colour())

class YellowPerson(Person):

    def __person_colour(self):
        return "I'm yellow person from child class."

yellow = YellowPerson('yellow')
yellow.print_person_colour() # I'm yellow person from parent class.
print(dir(yellow)) # ['_Person__colour', '_Person__person_colour', '_YellowPerson__person_colour',...]

xx__

xx_用来和Python预留的关键字做区分,如何你想使用Python预留的关键字做变量名或者方法名,你可以在其后面加两个下划线,但是不建议这样做,这样会导致代码混乱,不易阅读和维护

class Hello:

    def __init__(self, class__):
        self.class__ = class__

    def __init____(self):
        print(self.class__)

hello = Hello('World')
hello.__init____()

__xx__

__xx__作为Python魔术方法,它具有强大的功能,魔术方法的存在,使得Python被称为鸭子类型,就是说当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子

  • 代码足以说明问题,只要定义了__add__ 魔术方法,就说明你可以进行加减乘除等操作
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

参考文档

python _、__和__xx__的区别