• 多态,封装,反射,类内置attr属性,os操作复习


    1.多态

    #多态
    多态是指对象如何通过他们共同的属性和动作来操作及访问,而不需要考虑他们具体的类
    运行时候,多种实现 反应运行时候状态
    class H2O:
        def __init__(self,name,temperature):
            self.name = name
            self.temperature = temperature
        def turn_ice(self):
            if self.temperature < 0:
                print("[%s]温度太低结冰了" %self.name)
            elif self.temperature > 0 and self.temperature < 100:
                print("[%s]液化成水" %self.name)
            elif self.temperature > 100:
                print("[%s]温度太高变成了水蒸气" %self.name)
        def aaaaaaa(self):
            pass
    class Water(H2O):
        pass
    class Ice(H2O):
        pass
    class Steam(H2O):
        pass
    w1=Water("",25)
    i1=Ice("",-20)
    s1=Steam("蒸汽",3000)
    
    w1.turn_ice()
    i1.turn_ice()
    s1.turn_ice()
    
    #以下作法,同上
    def func(obj):
        obj.turn_ice()
    func(w1)
    func(i1)
    func(s1)

    类的继承有两层含义:1.改变 2.扩展

    多态就是类的这两层意义的一个具体的实现机制,即,调用不同的类实例化得对象下的相同方法,实现的过程不一样。python中的标准类型就是多态概念的一个很好的示范。

    2.封装prt1

    class People:
        __star = "earth"
        __star1 = "earth123"
        __star2 = "earth456"
        __star3 = "earth789"
        def __init__(self,id,name,age,salary):
            print("---->",self.__star)
            self.id = id
            self.name = name
            self.age = age
            self.salary = salary
        def get_id(self):
            print("我是私有方法啊,我找到的ID是[%s]" %self.id)
        #访问函数
        def get_star(self):
            print(self.__star)
    # print(People.__dict__)
    p1 = People("123456789","alex","18",100000)
    # print(p1.__star)
    # print(People.__dict__)
    # print(p1.__star)
    print(p1._People__star) #方法1访问__star="earth"
    p1.get_star() #方法2访问__star="earth"

    将上述代码文件导入test模块。

    from package import People #先运行package中代码,接着运行test中代码
    p1 = People("123123123123","alex","18",100) #调用People类
    p1.get_id() #调用get_id()函数

     3.反射

    反射使程序在运行时,动态修改自己结构和行为的能力

    反射作用具体化:A在写程序,要用到B的类,B不在上班,A调用反射机制继续写代码,等到B完成后,再实现B部分类的功能

    getattr()动态获取属性值

    setattr()设置属性值

    hasattr()用于判断对象是否具有属性值

    class BlackMedium:
        feture = "Ugly"
        def __init__(self,name,addr):
            self.name = name
            self.addr = addr
        def sell_house(self):
            print("[%s]正在卖房子,傻逼才买呢" %self.name)
        def rent_house(self):
            print("[%s] 正在租房子,傻逼才租呢" %self.name)
    b1 = BlackMedium("万成置地","天露网")
    print(b1.__dict__)
    #getattr和setattr用于获取和设置
    # hasattr() 用于判断object对象中是否存在name属性值,属性包含变量和方法,有则返回True,没有则返回False
    print(hasattr(b1,"name"))
    print(hasattr(b1,"sell_house"))
    print(getattr(b1,"name"))
    print(getattr(b1,"rent_house"))
    func=getattr(b1,"rent_house")
    func()
    print(getattr(b1,"111","234")) #如果不存在对象“111”,输出默认值“234”
    # b1.sb = True
    
    setattr(b1,"sb",True)
    setattr(b1,"sb1",123)
    setattr(b1,"name","SB") #修改name的value
    print(b1.__dict__)
    
    del b1.sb #删除对象的第一种操作
    # del b1.sb1
    # delattr(b1,"sb") #删除对象的第二种
    print(b1.__dict__)

    例子:

    列出ftp_client和yuyukun_client的py文件;

    运行程序;

    图1 B中处理的工作

    图2 A中运行程序的结果

    图3 A中运行程序的结果(get到B中的put对象)

    实例作为参数传入匿名函数中,实例同时也可调用自己

    #实例作为参数传入,可以调用
    class BlackMedium:
        feture = "Ugly"
        def __init__(self,name,addr):
            self.name = name
            self.addr = addr
        def sell_house(self):
            print("[%s]正在卖房子,傻逼才买呢" %self.name)
        def rent_house(self):
            print("[%s] 正在租房子,傻逼才租呢" %self.name)
    b1 = BlackMedium("万成置地","天露网")
    setattr(b1,"func",lambda x:x+1)
    setattr(b1,"func1",lambda self:self.name+"sb")
    print(b1.__dict__)
    print(b1.func(5))
    print(b1.func1(b1))

    4.动态模块导入_顶级模块名和当前模块名区别

    顶级模块可调用函数中内容

    当前模块不能调用函数中内容

    图4 顶级模块名和当前模块名区别

    当外部模块有下划线时,导入注意点以及如何导入外部所有模块

    动态导入底层基于反射

    # module_t.t.test1()
    from m1.t import * #用*导入m1/t中所有文件,不能调用 
    test1()
    _test2()
    
    #模块函数中加入“_”,不能在其他文件中调用,可以用下划线方式调用导入
    from m1.t import test1,_test2
    test1()
    _test2()

    6.类内置attr属性:根据自己状态来检验

    6.1类中4个内置函数

    hasattr(),hasattr(obj,"name") --> 判断“name”是否存在,返回True or False  

    getattr(), getattr(obj,"name",default = "xxx") --> 获取“name” 值,不存在返回xxx  getattr()找不到对象出发

    setattr(),setattr(obj,"name","alex") --> obj.name="alex"  setattr()设置属性时出发

    delattr(),delattr("obj","name") --> del obj.name  delattr()删除属性时出发

    实例调用对象触发4个类内置属性,该方法与类本身无关,与实例‘.’该调用方法有关。

    class Foo:
        x = 1
        def __init__(self,y):
            self.y = y
    
        def __getattr__(self, item):
            print("执行__getattr__")
    
        def __delattr__(self, item):
            print("删除操作__delattr__")
    
        def __setattr__(self, key, value):
            print("__setattr__执行")
            self.__dict__[key] = value
    f1 = Foo(10)
    print(f1.y)
    print(getattr(f1,"y"))
    f1.ssss
    
    del f1.y #删除触发__delattr__
    del f1.x
    
    f1 = Foo(10)
    print(f1.__dict__)
    f1.z = 2
    print(f1.__dict__)
    代码运行结果:
    __setattr__执行
    10
    10
    执行__getattr__
    删除操作__delattr__
    删除操作__delattr__
    __setattr__执行
    {'y': 10}
    __setattr__执行
    {'y': 10, 'z': 2}

    上述代码解释:其中delattr(),setattr()操作触发对应函数功能,调用getattr()不触发对应函数功能,只有在get不到类中的对象时,才会触发getattr()函数

    6.2 类中其它函数

    isinstance(obj,cls) 

    #判断对象名是否和类一致
    class
    Foo: pass f1 = Foo() print(isinstance(f1(f1是对象名),Foo(Foo是类)))

    issubclass(sub,super)

    #判断类1是否是类2的子类/继承类
    class Foo:
        pass
    f1 = Foo()
    print(isinstance(f1,Foo))
    
    class Bar(Foo):
        pass
    print(issubclass(Bar(类1),Foo(类2)))

     6.3 __getattr__, __getattribute__

    class Foo:
        def __init__(self,x):
            self.x = x
    
        def __getattr__(self, item):
            print("执行的是getattr")
        #     return self.__dict__[item]
    
        def __getattribute__(self,item):
            print("执行的是getattribute")
            # print("执行的是getattribute")
            # raise AttributeError("抛出异常了")
            raise TabError("xxxxx")
    
    f1 = Foo(10)
    # f1.x
    f1.xxxxxx123 
    #找不到对象,执行getattr()语句
    #或者找到对象,输出类中正常数值
    #getattr与getattribute区别
    #__getattr__触发时机,通过__getattribute__中的raise AttributeError来识别异常,并返回给getattr
    #TabError触发,进入中止程序

     7.二次加工:继承与派生。用于定制自己的数据类型,查看类型

    #二次加工标准类型(包装用于定制自己的数据类型)
    class List(list):
        def append(self, p_object): #l1=self,p_object=11111
            if type(p_object) is str:
                # list.append(self,p_object)
                super().append(p_object)
            else:
                print("只能添加字符串类型")
        def show_middle(self):
            mid_index = int(len(self)/2)
            return self[mid_index]
    
    l1 = List("hello_world")
    l1.append(12345)
    l1.append("SB") #自动触发 def append(self, p_object)
    print(l1)
    
    l2 = list("hello_world")
    print(l2,type(l2))
    
    print(l1,type(l1))
    print(l1.show_middle())

    8.组合方式完成授权(权限管理),防止对象权限滥用

    包装=继承+派生

    import time
    class FileHandle:
        def __init__(self,filename,mode="r",encoding="utf-8"):
            self.file = open(filename,mode,encoding=encoding)
            self.mode = mode
            self.encoding = encoding
    
        def write(self,line):
            # print("--->",line)
            t = time.strftime("%Y-%m-%d %X")
            self.file.write("%s %s" %(t,line))
    
        def __getattr__(self,item):
            # print(item,type(item))
            # self.file.read
            return getattr(self.file,item)
            # getattr(self.file,item)
    
    f1 = FileHandle("a.txt","w+")
    print(f1.file)print("-->",f1.read)f1 = FileHandle("a.txt","w+")print(f1.file)print(f1.__dict__)print("-->",f1.read)print(f1.write)
    f.write("12345
    ")
    f1.write("cpu负载过高
    ")
    f1.write("内存剩余不足
    ")
    f1.write("硬盘剩余不足
    ")
    f1.seek(0)
    print("-->",f1.read)

     9.os操作

    9.1 逐行输出系统路径

    print(sys.path)
    for i in sys.path:
        print(i)

    9.2 获取版本号

    print(sys.version)

    9.3 更改当前工作目录,当前python脚本工作的目录路径

    print(os.getcwd())

    9.4 更改当前目录

    os.chdir("D:\yuyukun")

    9.5 在当前目录下创建多层子文件夹

    os.makedirs(r"aabcc")

    9.6 删除目录 如果当前目录下有文件,不删除

    os.removedirs(r"aabcc")

    9.7 以列表形式列出当前目录下所有文件和文件夹

    print(os.listdir(os.getcwd()))

    9.8 输出当前目录file信息,查看信息,用于上传信息

    print(os.stat("file.py").st_size)

    9.9 重命名文件夹包

    os.rename("bb","ff")

    9.10 显示所有信息

    os.system("dir")

    9.11 显示当前文件所在目录

    print(__file__)

    9.12 返回path规范化的绝对路径

    print(os.path.abspath(__file__))

    9.13 获取系统环境变量

    os.environ

    9.13 将文件所在目录分成目录和文件两部分

    print(os.path.split(os.path.abspath(__file__)))

    9.14 返回当前文件的上一级目录 必须是绝对路径

    print(os.path.dirname(os.path.abspath(__file__)))

    9.15 判断path是否存在,判断path的绝对路径是否存在,判断path是否有一个存在的目录,判断path是否是一个存在的目录

    os.path.exists(path)
    os.path.isabs(path)
    os.path.isfile(path) 
    os.path.isdir(path)

    9.16 在__file__目录下新建aa文件夹,同时将123.txt文件附放到aa文件夹下,实现路径拼接

    print(os.path.dirname(os.path.abspath(__file__)))
    print(os.path.join(os.path.dirname(os.path.abspath(__file__)),"aa","123.txt"))

     10. item系列方法,查资料,理解资料,整理资料

    class Foo:
        def __getitem__(self, item):
            print("getitem",item)
            return self.__dict__[item]
        def __setitem__(self, key, value):
            print("setitem")
            print('setitem')
            self.__delitem__[key] = value
        def __delitem__(self, key):
            print("delitem")
            self.__dict__.pop(key)
    f1 = Foo()
    print(f1.__dict__)
    f1["name"] = "alex" #字典方式设置,触发setitem
    f1[1] = "2222"
    f1["age"] = 18
    del f1["name"]
    print(f1.__dict__)
    # del f1.name #不触发delitem()
    # print(f1.age)
    print(f1.__dict__)
    #总结:点方式操作属性,与实例有关,触发attr
            #[]方式操作属性,与系列有关,触发item

     11.__str__和__repr__

    str函数为打印输出函数,obj.__str__()

    repr函数为交互式解释器,obj.__repr__()

    如果__str__没有被定义,那么就会使用__repr__代替输出

    str和repr返回值必须字符串,否则输出异常

    class Foo:
        def __init__(self,name,age):
            self.name = name
            self.age = age
        def __str__(self):
            return "名字是%s 年龄是%s" %(self.name,self.age)
        def __repr__(self):
            return "名字是%s 年龄是%s" %(self.name,self.age)
    f1 = Foo("alex",25)
    print(f1.__str__())
    
    c = str(f1)
    print(c)
    
    print(f1)
    #以上三种写法相同
    #str(f1)-----> f1.__str__()-----> f1.__repr__()

    12.format表达形式,专门定制

    format_dic={
        "ymd":"{0.year}{0.mon}{0.day}",
        "m-d-y":"{0.mon}-{0.day}-{0.year}",
        "y:m:d":"{0.year}:{0.mon}:{0.day}"
    }
    class Date:
        def __init__(self,year,mon,day):
            self.year = year
            self.mon = mon
            self.day = day
        def __format__(self, format_spec):
            if not format_spec or format_spec not in format_dic:
                format_spec = "ymd"
            fm = format_dic[format_spec]
            return fm.format(self)
    d1 = Date("2019","04","09")
    print(format(d1,"ymd"))
    print(format(d1,"m-d-y"))
    print(format(d1,"y:m:d"))
    print(format(d1,"dfsdffdfsfd"))

     13.slots属性: slots生成一种更为紧凑的内部表示,实例通过一个很小的固定大小的数组来构建,而不是为每个实例定义一个字典, __slots__是定义在类中的类变量

    class Foo:
        __slots__ = ["name","age"]
        # __slots__ = "name"
    f1 = Foo()
    # print(Foo.__slots__)
    # print(f1.__slots__)
    f1.name = "alex"
    f1.age = 17 #类中必须具有name和age这两个变量,否则报错
    print(f1.name)
    print(f1.age)
    
    #类是一个共有事物,可以多次被调用
    f2 = Foo()
    print(f2.__slots__)
    f2.name = "jason"
    f2.age=25
    print(f2.name)
    print(f2.age)

    14. del析构函数,整个实例被删除,触发函数

    class Foo:
        def __init__(self,name):
            self.name = name
        def __del__(self):
            print("i am going on")
    f1 = Foo("alex")
    # del f1.name #整个实例被删除,触发函数
    print("--------->")

    15.__call__方法

    __call__ 构造方法的执行是由创建对象触发的,即:对象=类名();对于__call__方法的执行是由队形后加括号触发的,即:对象()或者类()()

    class Foo:
        def __call__(self, *args, **kwargs):
            print("实例执行啦 obj()")
    f1 = Foo()
    f1() #f1是一个实例,f1()调用的是Foo下的__call__方法
    Foo() #Foo是一个类,Foo()对应有对象abc,Foo()调用的是abc下面的__call__方法

    16. __iter__方法与__next__方法

    __iter__生成迭代器,__next__执行迭代器,超过阈值,用raise抛出异常

    #__next__与__iter__
    class Foo:
        def __init__(self,n):
            self.n = n
        def __iter__(self):
            return self
        def __next__(self):
            self.n += 1
            if self.n > 13:
                raise StopIteration
            return self.n
    f1 = Foo(10)
    print(f1.__next__())
    print(f1.__next__())
    print(f1.__next__())
    print(next(f1))

    例:斐波那契数列

    class Fib:
        def __init__(self):
            self.a = 1
            self.b = 1
        def __iter__(self):
            return self
        def __next__(self):
            if self.a > 100:
                raise StopIteration("stop")
            else:
                self.a,self.b = self.b,self.a+self.b
                return self.a
    f1 = Fib()
    print(next(f1))
    print(next(f1))
    print(next(f1))
    print(next(f1))
    print(next(f1))
    print("------------------>")
    for i in f1:
        print(i)

    17.描述符有限级:

    1类属性>2数据描述符>3实例属性>4非数据描述符>5找不到对象

    class Foo:
        def __get__(self, instance, owner):
            print("--->get方法")
        def __set__(self, instance, value):
            print("--->方法",instance,value)
            instance.__dict__["x"]=value #对Bar.__dict__字典赋值
        def __delete__(self, instance):
            print("--->delete方法")
        def __getattr__(self, item):
            print("can not find sth-------------------------------")
    class Bar:
        x = Foo()
        def __init__(self,n):
            self.x = n
        def __getattr__(self, item):
            print("can not find sth-------------------------------")
    # print(Bar.x) #类调用触发__get__方法
    # Bar.x = 1 #赋值操作不触发__get__方法
    # print(Bar.__dict__)
    # print(Bar.x)
    
    #实例属性,操作首先找数据描述符,其次找自己
    # b1 = Bar() #类属性>数据描述符(描述符优先级)
    # b1.x #触发__get__方法
    # b1.x = 1 #触发__set__
    # del b1.x #触发__del__方法
    
    b2 = Bar(10)
    print(b2.__dict__)
    #修改类实例------>12
    b2.x = 12  #打开__set__方法,实例属性字典中为空;关闭__set__方法,实例属性字典有值
    print(b2.__dict__)
    b2.xxxxxxxxxxxx #实例属性找不到,触发对应非数据描述符Bar的 __getattr__()

     18.跨py文件(from...import...)操作,人为添加环境变量

  • 相关阅读:
    C#成员设计建议
    基于任务的异步编程模式(TAP)的错误处理
    基于任务的异步编程模式(TAP)
    C#克隆
    C#操作excel打印
    父元素如何围住浮动子元素
    intellij idea创建第一个动态web项目
    Idea快捷键
    Python中列表的copy方法
    C++读取数量不定的数据
  • 原文地址:https://www.cnblogs.com/yuyukun/p/10652658.html
Copyright © 2020-2023  润新知