08私有化、MRO顺序

一. 私有化

1)xx: 公有变量

2)_x: 单前置下划线,私有化属性或方法,from somemodule import *禁止导入,类对象和子类可以访问

3)__xx:双前置下划线,避免与子类中的属性命名冲突,无法在外部直接访问(名字重整所以访问不到)

  • 父类中属性名为__名字的,子类不继承,子类不能访问
  • 如果在子类中向__名字赋值,那么会在子类中定义的一个与父类相同名字的属性

4)__xx__:双前后下划线,用户名字空间的魔法对象或属性。例如:__init__ , __ 不要自己发明这样的名字

5)xx_:单后置下划线,用于避免与Python关键词的冲突

二.多继承以及MRO顺序

1)super().__init__相对于类名.__init__,在单继承上用法基本无差

2)但在多继承上有区别,super方法能保证每个父类的方法只会执行一次,而使用类名的方法会导致方法被执行多次,具体看前面的输出结果

3)多继承时,使用super方法,对父类的传参数,应该是由于python中super的算法导致的原因,必须把参数全部传递,否则会报错

4)单继承时,使用super方法,则不能全部传递,只能传父类方法所需的参数,否则会报错

5)多继承时,相对于使用类名.__init__方法,要把每个父类全部写一遍, 而使用super方法,只需写一句话便执行了全部父类的方法,这也是为何多继承需要全部传参的一个原因

三.property属性

1. 定义与调用

1)定义时,在实例方法的基础上添加 @property 装饰器;并且仅有一个self参数

2) 调用时,无需括号,方法必须返回一个数

  方法:foo_obj.func()

  property属性:foo_obj.prop

class Foo:

    def func(self):

        pass

 

    # 定义property属性

    @property

    def prop(self):

        pass

 

# ############### 调用 ###############

foo_obj = Foo()

foo_obj.func()  # 调用实例方法

foo_obj.prop  # 调用property属性

2. 方式

2.1 装饰器

1)经典类中的属性只有一种访问方式,其对应被 @property 修饰的方法

class Goods:
    @property
    def price(self):
        return "laowang"
# ############### 调用 ###############
obj = Goods()
result = obj.price  # 自动执行 @property 修饰的 price 方法,并获取方法的返回值
print(result) 

2)新式类中的属性有三种访问方式,并分别对应了三个被@property、@方法名.setter、@方法名.deleter修饰的方法,分别将三个方法定义为对同一个属性:获取、修改、删除

class Goods:
    """python3中默认继承object类
        以python2、3执行此程序的结果不同,因为只有在python3中才有@xxx.setter  @xxx.deleter
    """
    @property
    def price(self):
        print('@property')
 
    @price.setter
    def price(self, value):
        print('@price.setter')
 
    @price.deleter
    def price(self):
        print('@price.deleter')
 
# ############### 调用 ###############
obj = Goods()
obj.price          # 自动执行 @property 修饰的 price 方法,并获取方法的返回值
obj.price = 123    # 自动执行 @price.setter 修饰的 price 方法,并将  123 赋值给方法的参数
del obj.price      # 自动执行 @price.deleter 修饰的 price 方法
2.2 类属性

1)当使用类属性的方式创建property属性时,经典类和新式类无区别

class Foo:
    def get_bar(self):
        return 'laowang'
 
    BAR = property(get_bar)
 
obj = Foo()
reuslt = obj.BAR  # 自动调用get_bar方法,并获取方法的返回值
print(reuslt)

 

2)property方法中有个四个参数

  • 第一个参数是方法名,调用 对象.属性 时自动触发执行方法
  • 第二个参数是方法名,调用 对象.属性 = XXX 时自动触发执行方法
  • 第三个参数是方法名,调用 del 对象.属性 时自动触发执行方法
  • 第四个参数是字符串,调用 对象.属性.__doc__ ,此参数是该属性的描述信息
class Foo(object):

    def get_bar(self):

        print("getter...")

        return 'laowang'

 

    def set_bar(self, value):

        """必须两个参数"""

        print("setter...")

        return 'set value' + value

 

    def del_bar(self):

        print("deleter...")

        return 'laowang'

 

    BAR = property(get_bar, set_bar, del_bar, "description...")

 

obj = Foo()

 

obj.BAR  # 自动调用第一个参数中定义的方法:get_bar

obj.BAR = "alex"  # 自动调用第二个参数中定义的方法:set_bar方法,并将“alex”当作参数传入

desc = Foo.BAR.__doc__  # 自动获取第四个参数中设置的值:description...

print(desc)

del obj.BAR  # 自动调用第三个参数中定义的方法:del_bar方法

 

posted @ 2019-02-15 11:47  菜白小系瓦  阅读(165)  评论(0编辑  收藏  举报