zoukankan      html  css  js  c++  java
  • python 面向对象

    面向对象设计(Object oriented design):将一类具体事物的数据和动作整合到一起,即面向对象设计

    面向对象编程(object-oriented programming):用定义类+实例/对象的方式去实现面向对象的设计

    1. 类和对象

    1.什么叫类:类是一种数据结构,就好比一个模型,该模型用来表述一类事物(事物即数据和动作的结合体),用它来生产真实的物体(实例)。

    2.什么叫对象:睁开眼,你看到的一切的事物都是一个个的对象,你可以把对象理解为一个具体的事物(事物即数据和动作的结合体)

    (铅笔是对象,人是对象,房子是对象,狗是对象,alex是对象,配齐是对象,元昊是对象)

    3.类与对象的关系:对象都是由类产生的,上帝造人,上帝首先有一个造人的模板,这个模板即人的类,然后上帝根据类的定义来生产一个个的人

    4.什么叫实例化:由类生产对象的过程叫实例化,类实例化的结果就是一个对象,或者叫做一个实例(实例=对象)

    类是用来描述一类事物,类的对象指的是这一类事物中的一个个体

    是事物就要有属性,属性分为

    1:数据属性:就是变量

    2:函数属性:就是函数,在面向对象里通常称为方法

    注意:类和对象均用点来访问自己的属性

    类的函数属性还没有传参数

    #注意:类和对象均用点来访问自己的属性
    
    class Chinese:
        "这个一个中国人的类"
        dang = "***"             #类的数据属性:就是变量
        def sui_di_tu_tan():       #类的函数属性:就是函数,在面向对象里通常称为方法
            print("吐了一口痰")
    
        def cha_dui(self):         #函数属性:就是函数,在面向对象里通常称为方法
            print("插到了前面")
    
    print(Chinese.dang)
    Chinese.sui_di_tu_tan()
    Chinese.cha_dui("先随便传一个参数")
    
    print("---------------")
    
    #类名.__dict__:查出的是一个字典,key为属性名,value为属性值
    print(Chinese.__dict__["dang"])        # __dict__ 里面存的是Chinese 的属性字典
    Chinese.__dict__["sui_di_tu_tan"]()    # 可以通过 __dict__ 里面的key调用Chinese的属性
    Chinese.__dict__["cha_dui"]("先随便传一个参数")
    

    类和对象

     #def __init__(self,name,age,gender): #实例化的过程可以简单理解为执行该函数的过程,实例本身会当作参数传递给self(这是默认的步骤)
    class Chinese:
        "这个一个中国人的类"
        dang = "***"              #类的数据属性:就是变量
    
        def __init__(self,name,age,gender):   #实例的数据属性
            self.mingzi = name
            self.nl = age
            self.xb = gender
    
        def sui_di_tu_tan(self):       #类的函数属性:就是函数,在面向对象里通常称为方法
            print("%s %s %s 吐了一口痰"%(self.mingzi,self.nl,self.xb))
    
        def cha_dui(self):         #类的函数属性:就是函数,在面向对象里通常称为方法
            print("%s 插到了前面"%self.mingzi)
    
    
    p1 = Chinese("tom",18,"男")    #实例化  创建一个对象p1
    
    print(p1.mingzi,p1.nl,p1.xb)    #打印实例的数据属性
    
    print(p1.__dict__)    # __dict__ 里面存的是p1 的属性字典
    print(p1.dang)   #先在实例(对象)的__init__的数据属性里找,找不到就找类的数据属性
    
    p1.sui_di_tu_tan()   #类的函数属性,会自动把p1传给self
    
    p1.cha_dui()    #类的函数属性,会自动把p1传给self
    

    类的增删改查

    class Chinese:
        councry = "china"
    
        def __init__(self,name):
            self.name = name
    
        def paly_ball(self,ball):
            print("%s 正在打 %s"%(self.name,ball))
    
    #查看类的数据属性
    print(Chinese.councry)
    
    #修改类的数据属性
    Chinese.councry = "Japan"
    print(Chinese.councry)
    
    # 实例化 创建一个对象
    p1 = Chinese("tom")
    print(p1.__dict__)
    
    #增加类的数据属性
    Chinese.dang = "***"
    print(Chinese.dang)
    
    #删除类的数据属性
    del Chinese.dang
    
    # 增加类的函数属性
    def eat_foot(self,foot):
        print("%s 正在吃 %s"%(self.name,foot))
    
    Chinese.eat = eat_foot    # 增加类的函数属性
    p1.eat("屎")
    
    
    # 对象调用类的函数属性
    p1.paly_ball("篮球")
    
    # 修改类的函数属性
    def test(self):
        print("test")
    
    Chinese.paly_ball = test   #修改类的函数属性
    p1.paly_ball()
    

    对象的增删改查

    class Chinese:
        councry = "china"
    
        def __init__(self,name):
            self.name = name
    
        def paly_ball(self,ball):
            print("%s 正在打 %s"%(self.name,ball))
    
    
    p1 = Chinese("tom")   #实例化 创建对象
    print(p1.__dict__)    #查看实例的数据属性
    
    #查看实例的数据属性
    print(p1.name)
    
    #增加实例的数据属性
    p1.age = 18
    print(p1.__dict__)
    
    #删除实例的数据属性
    del p1.age
    print(p1.__dict__)
    
    #修改实例的数据属性
    p1.name = "liaoboshi"
    print(p1.__dict__)
    

    特殊的类属性

    class ChinesePeople:
        '我们都是中国人,我们骄傲的活着,我们不服任何事和物'
        government='***'
        def sui_di_tu_tan():
            print('90%的中国人都喜欢随地吐痰')
    
        def cha_dui(self):
            print('一个中国人-->%s<--插到了前面' %self)
    
    print(ChinesePeople.__name__)# 类C的名字(字符串)
    print(ChinesePeople.__doc__)# 类C的文档字符串
    print(ChinesePeople.__base__)# 类C的第一个父类(在讲继承时会讲)
    print(ChinesePeople.__bases__)# 类C的所有父类构成的元组(在讲继承时会讲)
    print(ChinesePeople.__dict__)# 类C的属性
    print(ChinesePeople.__module__)# 类C定义所在的模块
    print(ChinesePeople.__class__)# 实例C对应的类(仅新式类中)
    

    静态属性

    class Room:
        def __init__(self,name,owner,le,wight,heigh):
            self.name = name
            self.owner = owner
            self.le = le
            self.wight = wight
            self.heigh = heigh
    
        @property     # 静态属性     把函数属性伪装成数据属性
        def cal_dz(self):
            return (self.le*self.wight*self.heigh)*0.5
    
    r = Room("房间","tom",2,2,2)
    print(r.cal_dz)
    

    静态方法

    class Room:
        tag = 1
        def __init__(self,name,owner):
            self.name = name
            self.owner = owner
    
        @staticmethod       #静态方法
        def wash_body(a,b,c):
            print("洗----->",a,b,c)
    
    Room.wash_body(1,2,3)       #类可以使用
    r = Room("房间","tom")
    r.wash_body(1,2,3)          #实例也可以使用
    

    类方法

    class Room:
        tag = 1
        def __init__(self,name,owner):
            self.name = name
            self.owner = owner
    
        @classmethod         # 类方法  专门给类使用,与实例无关  类方法只能访问类相关的属性,不能访问实例属性(与实例无关)
        def tell_info(cls):
            print(cls)
            print("----->",cls.tag)
    
    
    Room.tell_info()
    

    组合

    class School:
        def __init__(self,name,addr):
            self.name = name
            self.addr = addr
    
        def zhao_sheng(self):
            print("%s %s 正在招生"%(self.addr,self.name))
    
    
    class Course:
        def __init__(self,name,price,period,school):
            self.name = name
            self.price =price
            self.period = period
            self.school = school
    
    
    s1 = School("oldboy","北京校区")
    s2 = School("oldboy","深圳校区")
    s3 = School("oldboy","广州校区")
    
    c = Course("python",15800,"5M",s2)    #把学校的实例传进去
    print(c.__dict__)             # 输出 实例c 的属性字典
    c.school.zhao_sheng()         # 执行 实例s2 的zhao_sheng 函数属性
    

    继承 

    class Dad:
        money = 10
        def __init__(self,name):
            print("------Dad------")
            self.name = name
    
        def hit_son(self):
            print("%s 正在打son"%self.name)
    
    
    class Son(Dad):
        money = 10000
    
    
    
    
    s = Son("tom")                       # 实例Son的类,Son类中没有__init__方法,会调父类中的__init__方法,并且要传父类中要的参数
    print(s.money)  #===>10000           # 查看Son类的money属性 ,没有会找父类的
    s.hit_son()  #===>tom 正在打son      # 调用Son类的hit_son方法,没有会找父类的
    
    print(Dad.money) #===>10            # 子类和父类都有money的属性,子属的money属性不会覆盖父类的
    

    接口继承

    import abc
    
    class All_file(metaclass = abc.ABCMeta):
        @abc.abstractmethod           #子类要实例化,必须定义用@abc.abstractmethod 修饰的方法
        def read(self):
            pass
    
        @abc.abstractmethod
        def writ(self):
            pass
    
    
    class Disk(All_file):
        def read(self):
            print("disk read")
    
        def writ(self):
            print("disd writ")
    
    class Mem(All_file):
        def read(self):
            print("mem read")
    
        def writ(self):
            print("mem writ")
    
    m = Mem()       #想要实例,Mem类必须定义父类用@abc.abstractmethod修饰的方法
    m.read()
    m.writ()
    

    继承顺序

    class A:
        def test(self):
            print("A")
    
    class B(A):
        def test(self):
            print("B")
        # pass
    
    class C(A):
        def test(self):
            print("C")
        # pass
    
    class D(B):
        def test(self):
            print("D")
        # pass
    
    class E(C):
        def test(self):
            print("E")
        # pass
    
    class F(D,E):
        def test(self):
            print("F")
        # pass
    
    
    f = F()
    f.test()                          # 继承顺序有 深度优先和广度优先
    print("F的继承顺序",F.__mro__)     # python3 的继承顺序是广度优先
    

    在子类中调用父类的属性和方法(super方法的使用)

    class Vehicle:
        councry = "china"
        def __init__(self,name,speed,load,power):
            self.name = name
            self.speed = speed
            self.load = load
            self.power = power
    
        def run(self):
            print("开动了")
            print("开动了")
            print("开动了")
    
    class Subway(Vehicle):
        def __init__(self,name,speed,load,power,line):
            # Vehicle.__init__(self,name,speed,load,power)     #调用父类的__init__方法,不用再初始化一次
            super().__init__(name,speed,load,power)            #调用父类的__init__方法,不用再初始化一次
            self.line = line
    
        def test(self):
            print(self.name,self.speed,self.load,self.power,self.line)
    
        def run(self):
            # Vehicle.run(self)        # 可以运行子类与父类相同的 run 方法  不会只运行子类的 run 方法
            super().run()               # 可以运行子类与父类相同的 run 方法  不会只运行子类的 run 方法
            print(" %s 开动了"%self.name)
    
    
    s = Subway("北京地铁","100km/h",500,"电",13)     #实例s 
    s.test()           #通过实例s调用Subway的方法
    s.run()            #通过实例s调用子类和父类的run方法
    

    多态

    #类的继承有两层意义:1.改变 2.扩展
    #多态就是类的这两层意义的一个具体的实现机制
    #即,调用不同的类实例化得对象下的相同的方法,实现的过程不一样
    
    #python中的标准类型就是多态概念的一个很好的示范
    
    class H2o:
        def __init__(self,name,wd):
            self.name = name
            self.wd = wd
    
        def turn_ice(self):
            if self.wd < 0 :
                print("%s 温度小于0变冰了"%self.name)
            elif self.wd >0 and self.wd <100:
                print("%s 液化成水了"%self.name)
            elif self.wd >100 :
                print("%s 温度太高变水蒸气了"%self.name)
    
    class S(H2o):
        pass
    
    class Ice(H2o):
        pass
    
    class Szq(H2o):
        pass
    
    
    s = S("水",20)
    i = Ice("冰",-20)
    sz = Szq("水蒸气",120)
    
    def func(obj):
        obj.turn_ice()
    
    func(s)
    func(i)
    func(sz)
    

    封装

    class People:
        star = "地球"
        def __init__(self,id,name,age):
            self.name = name
            self.id = id
            self.age = age
    
    p = People("231243","tom",18)
    print(p.star)
    
    
    class People:
        _star = "地球11111"
        def __init__(self,id,name,age):
            self.name = name
            self.id = id
            self.age = age
    
    p = People("231243","tom",18)
    print(p._star)     # _属性名  的属性不建议在外面使用
    
    
    
    class People:
        __star = "地球222222"    #  __属性名  python 用自动重命名为 _类名__属性名   __属性名  的属性不建议在外面使用
        def __init__(self,id,name,age):
            self.name = name
            self.id = id
            self.age = age
    
    p = People("231243","tom",18)
    print(People.__dict__)
    print(p._People__star)    #  __属性名  python 用自动重命名为 _类名__属性名,如果通过 __属性名 会报错
    

    包装标准类型

    class List(list):
    
        def append(self, p_object):     #修改类List(list父类基础上)的append方法
            if type(p_object) is str:   #只能添加字符串
                super().append(p_object)
            else:
                print("只能加字符串")
    
        # def min(self):     # 在列表类的基础上加了一个可以查到列表中间元素的方法
        #     i = int(len(self)/2)
        #     return self[i]
    
    l = List("helloworld")
    print(l)
    
    # print(l.min())   #查看中间元素
    
    l.append("tom")
    print(l)
    

    反射

    class Heizj():
        def __init__(self,name,addr):
            self.name = name
            self.addr = addr
    
        def sell_house(self):
            print("%s 正在卖房子"%self.name)
    
    h = Heizj("万盛置地","天露园")
    print(hasattr(h,"name"))     #检测对象是否有这个属性
    
    #获取对象属性
    print(getattr(h,"name"))     #获取对象属性
    a = getattr(h,"sell_house")
    a()             #
    # print(getattr(h,"fjdiohg"))   #获取对象属性,没有这个属性就报错
    print(getattr(h,"fjdiohg","123"))    #获取对象属性,没有这个属性不报错,会输出第三个参数
    
    setattr(h,"sb","tom")    #设置属性,没有这个属性就添加到属性字典里
    setattr(h,"name","456")  #设置属性,有这个属性,就修改这个属性
    print(h.__dict__)        #查看属性
    
    delattr(h,"sb")      #删除属性
    # delattr(h,"fas")   #删除属性,没有就报错
    print(h.__dict__)    #查看属性
    

    双下划线attr方法系列

    class Foo:
        x = 1
        def __init__(self,y):
            self.y = y
    
        def __getattr__(self, item):
            print("__getattr__运行了")
    
    f = Foo(10)
    print(f.x)
    f.sssssssss   #运行的属性 当类里没有的时候 就自动会运行__getattr__方法
    
    
    class Foo:
        x = 1
        def __init__(self,y):
            self.y = y
    
        def __delattr__(self, item):
            print("__delattr__运行了")
    
    f = Foo(10)
    del f.x        #一有删除操作就会运行__delattr__方法
    del f.y
    
    
    class Foo:
        x = 1
        def __init__(self,y):
            self.y = y
    
        def __setattr__(self, key, value):
            print("__setattr__运行了")
            # self.key = value
            self.__dict__["key"] = value   #设置属性的时候会自动调用__setattr__, 上一行会无限递归,直接设置__dict__不会
    
    f = Foo(10)
    print(f.__dict__)
    f.z = 5
    print(f.__dict__)
    

    双下划线item方法系列

    # 触发双下划线item系列,要调用 f1["name"] ,就是要通过中括号去调用才会触发
    # 触发双下划线attr系列,要调用 f1.name ,就是要 点 去调用用才会触发
    
    class Foo():
        def __getitem__(self, item):
            print("__getitem__")
            return self.__dict__[item]
    
        def __setitem__(self, key, value):
            print("__setitem__")
            self.__dict__[key] = value
    
        def __delitem__(self, key):
            print("__delitem__")
            self.__dict__.pop(key)
    
    f1 = Foo()
    print(f1.__dict__)
    #f1.name = "tom"
    
    #__setitem__
    f1["name"] = "tom"
    f1["age"] = 18
    print("=====>",f1.__dict__)
    
    #__delitem__
    del f1["name"]
    print(f1.__dict__)
    
    #__getitem__
    print(f1["age"])
    

    授权:授权是包装的一个特性, 包装一个类型通常是对已存在的类型的一些定制,这种做法可以新建,修改或删除原有产品的功能。其它的则保持原样。授权的过程,即是所有更新的功能都是由新类的某部分来处理,但已存在的功能就授权给对象的默认属性。

    实现授权的关键点就是覆盖__getattr__方法

    import time
    class FileHandle:
        def __init__(self,filename,mode='r',encoding='utf-8'):
            self.file=open(filename,mode,encoding=encoding)
        def write(self,line):
            t=time.strftime('%Y-%m-%d %T')
            self.file.write('%s %s' %(t,line))
    
        def __getattr__(self, item):
            return getattr(self.file,item)
    
    f1=FileHandle('b.txt','w+')
    f1.write('你好啊')
    f1.seek(0)
    print(f1.read())
    f1.close()
    
    #授权示范一
    
    #_*_coding:utf-8_*_
    __author__ = 'Linhaifeng'
    #我们来加上b模式支持
    import time
    class FileHandle:
        def __init__(self,filename,mode='r',encoding='utf-8'):
            if 'b' in mode:
                self.file=open(filename,mode)
            else:
                self.file=open(filename,mode,encoding=encoding)
            self.encoding=encoding
    
        def write(self,line):
            t=time.strftime('%Y-%m-%d %T')
            if 'b' in self.mode:
                msg=bytes('%s %s' %(t,line),encoding=self.encoding)
            self.file.write(msg)
    
        def __getattr__(self, item):
            return getattr(self.file,item)
    
    f1=FileHandle('b.txt','wb')
    f1.write('你好啊啊啊啊啊') #自定制的write,不用在进行encode转成二进制去写了,简单,大气
    f1.close()
    
    #授权示范二
    

    __format__用法

    #自定义format练习
    
    date_dic={
        'ymd':'{0.year}:{0.month}:{0.day}',
        'dmy':'{0.day}/{0.month}/{0.year}',
        'mdy':'{0.month}-{0.day}-{0.year}',
    }
    class Date:
        def __init__(self,year,month,day):
            self.year=year
            self.month=month
            self.day=day
    
        def __format__(self, format_spec):
            if not format_spec or format_spec not in date_dic:
                format_spec='ymd'
            fmt=date_dic[format_spec]
            return fmt.format(self)
    
    d1=Date(2016,12,29)
    print(format(d1))
    print(format(d1,"dmy"))
    print(format(d1,"mdy"))
    

     __slots__方法

    #少用
    
    class Foo:
        __slots__ = ["name","age"]
    
    f1 = Foo()
    print(Foo.__dict__)
    f1.name = "tom"
    f1.age = 18
    
    # f1.gender = "man"  #不能设置__slots__里没有的属性
    
    print(f1.name)
    print(f1.age)
    
    # print(f1.__dict__)  #设置了__slots__,实例的对象没有__dict__的属性字典
    

     __del__方法    析构方法

    class Foo:
        def __del__(self):
            print("我执行了")
    
    
    f1 = Foo()
    del f1     #对象被删除时会调用__del__方法
    print("-------------->")
    
    #程序运行完时也会调用__del__方法,因为程序运行完,Python解释器会回收对象。
    

     __call__方法

    #  __module__ 表示当前操作的对象在那个模块
    #  __class__   表示当前操作的对象的类是什么
    
    class Foo:
        def __call__(self, *args, **kwargs):
            print("执行了---")
    
    f1 = Foo()
    
    f1()  # f1的类Foo 下的__call__方法. 如果上面没有定义__call__方法,调用f1()用报错
    
    Foo() # Foo的类 XXX 下的__call__方法
    

    一 isinstance(obj,cls)和issubclass(sub,super)

    isinstance(obj,cls)检查是否obj是否是类 cls 的对象

     class Foo(object):
         pass
      
     obj = Foo()
      
     isinstance(obj, Foo)
    

     issubclass(sub, super)检查sub类是否是 super 类的派生类

    class Foo(object):
        pass
     
    class Bar(Foo):
        pass
     
    issubclass(Bar, Foo)
    
  • 相关阅读:
    Pillar
    Minion配置文件
    Master配置文件
    Grains
    常见的散列函数
    数据结构散列表
    转载:数据结构 二项队列
    转载:数据结构 左式堆
    数据结构 d-堆
    二叉堆的简单介绍
  • 原文地址:https://www.cnblogs.com/liaoboshi/p/6201418.html
Copyright © 2011-2022 走看看