python基础(对象的进阶之三大属性)

一、对象继承:

  1.1 继承:

    特点:

      提高代码的重用性,减少了代码的冗余
      父类是object的类 —— 新式类,在Python3版本之后都是新式类
      类总是要调用init方法,如果我们不写,实际上就调用父类object的__init__方法了
      继承中使用属性时,如果自己有 就用自己的,如果自己没有 就用父类的,如果父类也没有 就报错

    继承思想:

      对象 -->类 -->基类
      基类 -继承-> 子类 -实例化-> 对象

  1.2 单继承:

    特点:
      可以有效的帮我们提高代码的重用性
      在子类和父类有同名方法的时候,默认只执行子类的方法
      如果想要执行父类的方法,可以在子类的方法中通过父类的类名调用父类的方法

    单继承示例:

  
# 动物属性继承示例:


class Animal(object):
    def __init__(self, name, kind):
        self.name = name
        self.kind = kind

    def eat(self, food):
        print('%s eat %s' % (self.name, food))

猫的属性继承:
class Cat(Animal):   # 派生属性
    def __init__(self, name, kind, eyes_color):
        self.eyes_color = eyes_color
        # super(Cat,self).__init__(name,kind)  # 前面的类名和self可以忽略不写(方式一)
        # super().__init__(name,kind)   # self参数默认传参,不需要指定(方式二)
        Animal.__init__(self, name, kind)   # 通过父类类名传参(方式三)

    def climb(self):              # 派生方法
        print('%s climb tree'%self.name)

狗的属性继承:
class Dog(Animal):pass


hua = Cat('小花', '橘猫', '蓝色')
print(hua.__dict__)  # 打印对象的属性字典
View Code

  1.3 多重继承:

    特点:

      规范复杂的功能与功能之间的关系
      在多继承中,super方法就只和mro顺序有关系,和父类子类没有关系

    多重继承示例:

  
# 多继承示例:

# 各种动物,每一种动物都是一个类
# 青蛙、天鹅、老虎、鹦鹉
# 青蛙 :走,游泳
# 天鹅 :走,游泳,飞
# 老虎 :走,游泳
# 鹦鹉 :走,飞,说话

# 定义飞禽类
class FlyAnimal:
    def fly(self):pass

# 定义水生类
class SwimAnimal:
    def swim(self):pass
    def eat():pass

# 定义的走兽类
class WalkAnimal:
    def walk(self):pass
    def eat():pass

# 青蛙继承的类
class Frog(SwimAnimal,WalkAnimal): pass
# 老虎继承的类
class Tiger(SwimAnimal,WalkAnimal):pass
# 天鹅继承的类
class Swan(FlyAnimal,SwimAnimal,WalkAnimal):pass
# 鹦鹉继承的类
class Parrot(FlyAnimal,WalkAnimal):
    def talk(self):
        pass
View Code

  继承时如果出现多个和父类都有,那么用谁的?

  1.4  多继承之钻石继承问题:

     图例: 广度优先

  

     钻石继承示例:

  
# 钻石继承示例:
# 遵循原则: 广度优先(C3算法)

class A(object):
    def func(self):
        print('a')

class B(A):
    pass
    # def func(self):
    #     print('b')

class C(A):
    pass
    # def func(self):
    #     print('c')

class D(B,C):
    pass
    # def func(self):
    #     print('d')

d = D()
d.func()   # d --> b --> c --> a
View Code

  1.5 多重继承之乌龟继承问题:

    图例:

  

    乌龟继承示例:

  
# C3算法是怎么计算的:
class A(object):
    def func(self):
        print('a')

class B(A):
    pass
    # def func(self):
    #     print('b')

class C(A):
    pass
    # def func(self):
    #     print('c')

class D(B):
    pass
    # def func(self):
    #     print('d')

class E(C):
    pass
    # def func(self):
    #     print('e')

class F(D,E):
    pass
    # def func(self):
    #     print('f')
f = F()
f.func()
print(F.mro())   # 就是帮助我们来展示c3算法的继承顺序 FDBECAO
View Code

    乌龟继承之C3算法剖析:

  
C3算法剖析:

元素提取提取规则:
    每次获取一个类
    如果从左到右第一个类,
    在后面的继承顺序中也是第一个,或者不再出现在后面的继承顺序中
    那么就可以把这个点提取出来,作为继承顺序中的第一个类

A= [AO]

B = B ,[AO]
B这个节点的继承顺序 :[BAO]

C = C ,[AO]
C这个节点的继承顺序 :[CAO]

D = D ,[BAO]
D这个节点的继承顺序 :[DBAO]

E = E ,[CAO]
E这个节点的继承顺序 :[ECAO]

F = E ,[DBAO],[ECAO]
F这个节点的继承顺序 :[DBAO],[ECAO]

定义L列表:
这里根据规则进行筛选排序:
L[F] = F,[DBAO],[ECAO]
[F] = [DBAO],[ECAO]
[FD] = [BAO],[ECAO]
[FDB] = [AO],[ECAO]
[FDB] = [AO],[ECAO]
[FDBE] = [AO],[CAO]
[FDBEC] = [AO],[AO]
[FDBECA] = [O],[O]
[FDBECAO]  # 最终的继承顺序
View Code

 二、 对象的多态:

  2.1 type 与 class 关系:

    概念:

      对象是被创造出来 被类实例化出来的
      类也是被创造出来的 特殊的方式来创造类

    分类:
      常规创造的类: 总是有几个特性
        能够实例化
        能有属性
        能有方法
      元类 :能够帮助你创造不同寻常的类
        特殊的需求一 : 不能实例化
        特殊的需求二 : 只能有一个实例

    图例:

  

    示例:

  
# 一切皆对象:

class A:pass   # 自己创建类

print(type(A))  # 自建类
print(type(int))   # 内置类
print(type(str))
View Code

    总结:

      类 = type(对象)
      type = type(类)

   2.2 归一化设计:

    2.2.1 抽象类:

      特点:

        单继承的规范
        约束所有的子类 必须实现被abstractmethod装饰的方法名
        给我们的代码制定规范(规则)
        抽象类不能实例化,只是作为具体的类的规范

        抽象类里面定义的所有的抽象方法 内部是可以完成一些简单的代码

      示例:

  
# 抽象类设计示例:

from abc import ABCMeta, abstractmethod

# 规范:
# 之所以写一个pay是为了提醒所有子类你一定要实现一个pay方法
class Payment(metaclass=ABCMeta):    # 抽象类

    # 付钱
    @abstractmethod   # 如果我必须要实现pay方法,那么我需要给pay加一个装饰器
    def pay(self):
        pass   # 创建的这个pay并没有内容,

    # 退款
    @abstractmethod
    def back(self):
        pass


# 程序设计:
# 微信支付:
class Wechatpay(Payment):
    def __init__(self,name,money):
        self.name = name
        self.money = money
    def pay(self):
        print('%s通过微信支付了%s元'%(self.name,self.money))

# 支付宝支付:
class Alipay(Payment):
    def __init__(self,name,money):
        self.name = name
        self.money = money
    def pay(self):
        print('%s通过支付宝支付了%s元'%(self.name,self.money))

# apple支付:
class ApplePay(Payment):
    def __init__(self, name, money):
        self.name = name
        self.money = money
    def pay(self):
        print('%s通过apple pay支付了%s元' % (self.name, self.money))
    def back(self):
        print('退款')

# 归一化设计接口:
def pay(person):
    person.pay()

# 实例化一个对象
ApplePay('alex',20000)
View Code

    2.2.2 接口类:

      特点:

        多继承的规范
        接口类里面定义的所有的接口方法 内部是可以完成一些简单的代码

  
# 接口类示例:

from abc import ABCMeta,abstractmethod

# 接口规范:
# 动物都有的特性:
class NormalAnnimal(metaclass=ABCMeta):
    #
    @abstractmethod
    def eat(self):pass

    #
    @abstractmethod
    def drink(self):pass

# 程序设计:
# 飞禽类:
class FlyAnimal(metaclass=ABCMeta):
    @abstractmethod
    def fly(self):pass

# 水生类:
class SwimAnimal(metaclass=ABCMeta):
    @abstractmethod
    def swim(self):pass

# 陆生类
class WalkAnimal(metaclass=ABCMeta):
    @abstractmethod
    def walk(self):pass



# 接口类实现多继承:
class Frog(NormalAnnimal,SwimAnimal,WalkAnimal):pass
class Tiger(NormalAnnimal,SwimAnimal,WalkAnimal):pass
class Swan(NormalAnnimal,FlyAnimal,SwimAnimal,WalkAnimal):pass
class Parrot(NormalAnnimal,FlyAnimal,WalkAnimal):
    # 特殊方法:
    def talk(self):
        pass
View Code

  2.3 多态:

    定义:

      广义:多态指的是一类事物有多种形态,动物可以表现成猪\狗\羊

      狭义 : 在函数接收参数的时候,接收的多个类的对象同属于一个父类

    特点:

      对扩展开放(Open for extension):允许子类重写方法函数

      对修改封闭(Closed for modification):不重写,直接继承父类方法函数

    示例一:

  
class Person(object):
    def __init__(self,name,sex):
        self.name = name
        self.sex = sex

    def print_title(self):
        if self.sex == "male":
            print("man")
        elif self.sex == "female":
            print("woman")

class Child(Person):                # Child 继承 Person
    def print_title(self):
        if self.sex == "male":
            print("boy")
        elif self.sex == "female":
            print("girl")

May = Child("May","female")
Peter = Person("Peter","male")

print(May.name,May.sex)
print(Peter.name,Peter.sex)
May.print_title()
Peter.print_title()
View Code

    示例二:

  
import abc
class Animal(metaclass=abc.ABCMeta): #同一类事物:动物
    @abc.abstractmethod
    def talk(self):
        pass

class People(Animal): #动物的形态之一:人
    def talk(self):
        print('say hello')

class Dog(Animal): #动物的形态之二:狗
    def talk(self):
        print('say wangwang')

class Pig(Animal): #动物的形态之三:猪
    def talk(self):
        print('say aoao')
View Code

  2.4 鸭子类型:

    描述:

      我们只是通过一种潜规则的约定,如果具有__iter__,__next__就是迭代器
      如果具有__hash__方法就是可哈希
      如果具有__len__就是可以计算长度的

    定义:

      数据类型之间的关系并不仅仅是通过继承来约束的
      是通过约定俗成的关系来确认的

    示例:

  
#二者都像鸭子,二者看起来都像文件,因而就可以当文件一样去用
class TxtFile:
    def read(self):
        pass

    def write(self):
        pass

class DiskFile:
    def read(self):
        pass
    def write(self):
        pass
View Code

 三、封装:

  3.1 私有化:

    定义:

      广义上的封装 : 把方法和属性根据根据类别装到类中
      狭义上的封装 : 私有化的方法和属性

    格式:

      把一个属性加上双下划线 __属性名

      类似:__price

    特点:

      类的外部不能私有化(_类名__属性)变量,类的私有化是在类的内部完成,外部是不能访问或者查看的

      方法\静态变量\实例变量(对象属性)都可以私有化
      实例变量(对象属性),静态变量(类变量),方法都不能被子类继承

    私有化的两种形态(属性 + 方法):

  
# 私有化对象属性和类属性:

class Goods:

    __weight = 5  # 静态变量的私有化

    def __init__(self, name, price):
        self.name = name
        self.__price = price    # 私有对象属性

    def get_price(self):
        print(self.__price)


apple = Goods('苹果', 5)
print(apple.name)
print(apple._Goods__price)   # 私有对象属性的强制性获取,不建议使用
print(apple.__dict__)


# 私有的方法:

import hashlib

class Auth:
    def __init__(self, user, pwd):
        self.username = user
        self.password = pwd

    # 私有化的方法,外部不能访问
    def __md5_code(self):
        md5 = hashlib.md5(self.username.encode('utf-8'))
        md5.update(self.password.encode('utf-8'))
        return md5.hexdigest()

    def login(self):
        if self.username == 'alex' and 'ee838c58e5bb3c9e687065edd0ec454f' == self.__md5_code():
            return True

user = input('>>>')   # 获取名字
pwd = input('>>>')   # 获取密码
obj = Auth(user, pwd)
ret = obj.login()
if ret:
    print('登陆成功')
View Code

  3.2 property 属性:

    格式:

    @属性
    def 方法名(self):
      语句体

    property示例:

  
# 示例:

# 计算圆形的面积 + 周长:

class Circle:
    def __init__(self, r):
        self.r = r

    @property  # 把装饰的一个方法伪装成一个属性
    def area(self):
        return 3.14 * self.r ** 2

    @property
    def perimeter(self):
        return 2 * 3.14 * self.r


c1 = Circle(5)
print(c1.area)   # 面积
print(c1.perimeter)   # 周长
View Code

    property 与 私有化:

  
# property属性 与 私有化:

# 示例:

class Goods:

    discount = 0.8   # 静态变量

    def __init__(self, name, price):
        self.name = name
        self.__price = price   # 私有化变量

    @property
    def price(self):
        # return self.__price * Goods.discount   # 内部类调用静态变量(不建议使用)
        return self.__price * self.discount   # 通过对象调用静态变量


# 苹果实例
apple = Goods('苹果', 5)
print(apple.name)
print(apple.price)

# 香蕉实例
banana = Goods('香蕉', 10)
print(banana.name)
print(banana.price)
View Code

  3.3 property 与 setter 方法:

    格式:

      @属性.setter
      def 方法名(self,value):
        条件:
          修改属性

    特点:

      必须被property伪装
      必须为property伪装的方法名同名

  
# 示例:

class Goods:

    discount = 0.8

    def __init__(self, name, price):
        self.name = name
        self.__price = price

    # 被property装饰的price方法
    @property
    def price(self):
        p = self.__price * self.discount
        return p

    # 被setter装饰的price方法
    @price.setter
    def price(self, value):
        self.__price = value


apple = Goods('苹果', 5)
banana = Goods('香蕉', 10)
apple.price = 8     # 对应的调用的是被setter装饰的price方法
print(apple.price)  # 对应调用的是被property装饰的price方法
View Code

  3.4 property 与 deleter 方法:

    特点:

      类的方法,不支持修改,也不支持删除
      类的属性与对象的属性可以被删除

    格式:

      @属性.deleter
      def 方法名(self):
        del 删除属性

  
# 示例:

class Goods:

    discount = 0.8

    def __init__(self, name, price):
        self.name = name
        self.__price = price   # 私有化变量

    @property
    def price(self):
        return self.__price * self.discount

    @price.deleter
    def price(self):
        del self.__price
        print('执行我啦')


apple = Goods('苹果', 5)
print(apple.name)
print(apple.price)

# 删除 私有化的对象属性(__price)
del apple.price

print(apple.__dict__)   # 查看类属性字典
View Code

  3.5 类方法(classmethod):

    特点:

      类方法需要至少一个默认参数 cls
      类方法修改的是类中的静态变量/类变量
      类方法不会和self有任何的操作关联
      类方法接收的是当前我们所在的类的所有操作
      类方法推荐使用类名调用而不是使用对象名调用

    示例:

  
# 示例一:

class Fruits:
    __discount = 0.8

    def __init__(self, name, price):
        print('init', self)
        self.name = name
        self.__price = price

    # 把一个方法从对象方法,变成一个类方法
    @classmethod
    def change_discount(cls, value):   # cls 是:Fruits
        cls.__discount = value

    # 类方法表现形式一
    @classmethod
    def get_discount(cls):
        print(cls.__name__)   # 查看cls 类名
        return cls.__discount


print(Fruits.get_discount())  # 类名调用
Fruits.change_discount(1)
print(Fruits.get_discount())

# 示例二:

class Test(object):

    def abc(cls):
        print(cls.__name__)  # 打印类名

    # 类方法表现形式二
    abc = classmethod(abc)  # 通过普通的函数传参的方式创建类方法


a = Test()
Test.abc()  # 类能调用

a.abc()     # 实例也能调用,不建议通过实例调用
View Code

  3. 6 静态方法(staticmethod):

    特点:

      静态方法不需要默认参数
      静态方法其实就是类中的一个普通函数,它并没有默认传递的参数
      虽然静态方法没有默认参数, 但可以有参数

    示例:

  
# 示例一:

class A:
    @staticmethod
    def func():    # 此时 func是一个静态方法
        print('既不操作和self相关的内容')
        print('也不操作和类名相关的内容')


A.func()


# 示例二:

class Test(object):

    def abc():
        print('abc')

    # 静态方法表现形式一
    abc = staticmethod(abc)

    # 静态方法的表现形式二
    @staticmethod
    def xyz(a, b):
        print(a + b)


Test.abc()      # 类调用
Test.xyz(1, 2)  # 类调用

a = Test()
a.abc()      # 实例调用
a.xyz(3, 4)  # 实例调用
View Code

 

posted @ 2019-03-27 16:48  Amorphous  阅读(349)  评论(0编辑  收藏  举报