我的Python自学之路

python oop相关

2019-02-16  本文已影响15人  霡霂976447044
用于显示内置方法属性 __xxx__
__del__ 在对象销毁自动调用
# super是一个类,super()产生一个父类对象
class Father(object):
    def __init__(self):
        print("father init")
class Son(Father):
    def __init__(self):
        pass
son = Son()
# 没有输出任何信息,因为子类覆盖了父类的__init__方法。

class Father(object):
    def __init__(self):
        print("father init")
class Son(Father):
    def __init__(self):
        super().__init__()  # python3
        # Father.__init__(self) python2 不推荐
son = Son()
#基于父类的方法扩展也是使用super
 def anther_func(self):
     raise NotImplementedError
# 只能作为警告
class Father(object):
    def say(self):
        print("ba ba")
class Son(Father):
    def say(self):
        print("wa wa")
son = Son()
son.say()
# 输出
# wa wa
# 跟java的一样,子类覆盖父类方法
class MyClass(object):
    __slots = ['name', 'identifier']
    def __init__(self, name, identifier):
        self.name = name
        self.identifier = identifier
# 可以减小内存消耗
父类中使用 __(双下划线)开头属性或者方法子类即不可访问
# 使用 实例._类型__私有名 访问
class A:
    def __init__(self):
        self.name1 = "lisi"
        self.__name2 = "zhangsan"
    def __bar(self):
        print("bar")
class B(A):
    def foo(self):
        print(self._A__name2)
        self._A__bar()
b = B()
b.foo()
一般的,调用继承列表最近的类的方法 (在MRO查找 ClassType.mro())
python2不写继承object不会默认继承
python3默认不写也会继承自object
# 静态方法不访问实例(Dog())属性/方法以及类(Dog)属性/方法
class Animal(object):
    def talk(self):
        raise NotImplementedError
class Dog(Animal):
    def talk(self):
        print("wang wang wang")
    @staticmethod
    def get_dog():
        return Dog()
Dog.get_dog().talk()
#类方法只能访问类属性/方法
class Dog():
    name2 = "lisi" # 类属性
    def __init__(self):
        self.name1 = "zhangsan" # 实例属性
    def talk(self):
        print("wang wang wang")
    @classmethod
    def get_dog(cls): # 类方法
        # print("name %s" % cls.name1) 不能访问实例属性
        print("name %s" % cls.name2)
Dog.get_dog()
# 实例方法可以访问类属性、实例属性 访问类属性建议用ClassType访问
class Dog():
    name2 = "lisi"
    list1 = []
    def __init__(self):
        self.name1 = "zhangsan"
    def talk(self):
        print("类属性", self.name2)
        print("id(self.name2):", id(self.name2))
        self.name2 = "zhaoliu"
        self.list1.append("2")
        print("id(self.name2):", id(self.name2))
        print("实例属性", self.name1)
Dog.name2 = "wangwu"
Dog.list1.append("1")
dog1 = Dog()
dog1.talk()
print(Dog.name2)
print(Dog.list1)

输出

类属性 wangwu
id(self.name2): 140533652653872
id(self.name2): 140533652653592
实例属性 zhangsan
wangwu
['1', '2']

不可变的类属性通过self操作改变值不会影响其它实例。

在java中的多态: 父类引用指向子类对象(Father s = new Son(); s.talk()是子类的输出)

class Animal(object):
    def talk(self):
        raise NotImplementedError
class Dog(Animal):
    def talk(self):
        print("wang wang wang")
def play_with_animal(a):
    a.talk()
dog = Dog()
play_with_animal(dog)
class MusicPlayer(object):
    instance = None
    init_flag = False
    def __init__(self):
        if MusicPlayer.init_flag:
            return
        print("MusicPlayer init...")
        MusicPlayer.init_flag = True
    def __new__(cls, *args, **kwargs):
        print("new called")
        if not cls.instance:
            cls.instance = super().__new__(cls)  # 必须
        return cls.instance
    def play(self):
        print("playing music...")
player = MusicPlayer()
print(player)
player = MusicPlayer()
print(player)

super在使用中使用出错会造成父类,不正确的初始化。

Son(Father1, Father2) > super(Father1, self).init() 表示从Son.mro元组里面查找到Father1, 执行之后的init方法。请理解并执行下面的程序。

class Father(object):
    def __init__(self):
        print("Father called")
class Father1(Father):
    def __init__(self):
        # (<class '__main__.Son'>, <class '__main__.Father1'>, <class '__main__.Father2'>, <class '__main__.Father'>, <class 'object'>)
        print("Father1 init start")
        super(Father, self).__init__()  # 执行Father后面的object的__init__
        print("Father1 init over")
class Father2(Father):
    def __init__(self):
        print("Father2 init start")
        super(Father2, self).__init__() # 执行Father2后面的father的__init__
        print("Father2 init over")
class Son(Father1, Father2):
    def __init__(self):
        print("Son init start")
        # (<class '__main__.Son'>, <class '__main__.Father1'>, <class '__main__.Father2'>, <class '__main__.Father'>, <class 'object'>)
        # super(Father2, self).__init__()  # 执行Father2后面的Father对象的__init__
        # super(Father1, self).__init__()   # 执行Father1后面的Father2对象的__init__
        super(Son, self).__init__() # 同下
        # super().__init__() # 同上
        print("Son init over")
print(Son.__mro__)
son = Son()

每次调用super(ClassType)函数都是执行MRO列表的ClassType的下一个类型的方法
避免子类没有正确继承初始化,每一个类都应该写为super(ClassType,self).xxx 或者super().xxx

__class__ 获取的结果一般和type(Object)结果一样。
eg:   self.__classs__.__name__ 
上一篇 下一篇

猜你喜欢

热点阅读