• python笔记5 接口类抽象类 封装 反射 设计模式 模块 :random随机数 josn shelve持久化存储


     接口类抽象类

    接口类:接口类就是制定一个规则,让其他人按照我的规则去写程序.

    #!/usr/bin/env python
    from abc import ABCMeta,abstractmethod       #针对新手强制规定类的格式,不统一格式就报错
    class payment(metaclass=ABCMeta):          #类的模板,新加入的类必须沿用这个类的模型
        @abstractmethod
        def pay(self,money):
            pass
    class qqpay:
        def pay(self, money):
            print('QQ支付了%s元' % money)
    
    
    class alipay:
        def pay(self, money):
            print('阿里支付了%s元' % (money))
    
    class wechat:
        def pay(self, money):
            print('微信支付了%s元' % (money))
    
    def pay(fs,money):                #统一支付方式的函数 fs.pay(money)
    a1
    = qqpay()                #定义类的单个对象 a2 = alipay() a3 = wechat() pay(a1,50)          #支付的方式被统一

    封装

    类的三大特性:继承,封装,多态(python默认支持)

    类的结构:

    class A:
        country = 'china'  # 静态变量(属性,字段)
        __name__ = 'wk'  # 私有静态变量
    
        def func(self):  # 动态普通方法
            pass
    
        def __init__(self):  # 特殊方法,双下方法
            pass
    
        def __func(self, age):  # 私有方法
            self.__age = age     #私有对象属性
    
        @property     #属性
        def f1(self):
            pass
    
        @classmethod  # 类方法
        def f2(cls):
            pass
    
        @staticmethod  # 静态方法
        def f3():
            pass

    私有

    私有成员有:  私有变量,私有对象属性,私有方法

    class A:
        __name = 'wk'           #私有变量
    
        def __aa(self, age):    #私有方法
            self.__age = age    #私有对象属性
                        

     私有变量(私有变量和私有对象属性一样)

    class A:
        country = 'china'
        __name = 'wk'
    
        def __init__(self, name, xingbie):
            self.name = name
            self.__xingb = xingbie
    
        def aa(self):  
            print(self.__name)        #私有变量类外不能访问(print(bb.__name)报错),只能在本类内使用,子类继承父类一样不能调用父类私有变量
    bb = A('11',22)
    bb.aa()
    wk

    私有变量不是真实的找不到,而是变量名__name变成了_A__name,用_A__name就能找到私有变量

    class A:
        country = 'china'
        __name = 'wk'
    
        def __init__(self, name, xingbie):
            self.name = name
            self.__xingb = xingbie
    
        def aa(self):
            print(self.__name)
    
    class B(A):
        def ee(self):
            print(self.__name)
    
    bb = A('11',22)
    print(bb._A__name)            #私有变量前边加_A就能调用
    
    wk

     类方法

    @classmethod  用于改变类里的静态属性 ,(对象无法改变类的静态属性)   

    class A:
        country = 'china'
    
        def fun(self):
            pass
    
        def __init__(self, name):
            self.name = name
    
        @classmethod       #使用classmethod类方法,cls就是类A
        def fun2(cls):      
            print(cls)      
            cls.xixi = 321    #cls.xixi = A.xixi
    A.fun2()            #调用fun2
    print(A)
    c = A('wk')      
    print(c.xixi)          #对象c就能使用类里的方法

    <class '__main__.A'>
    <class '__main__.A'>

     

    记录有多少个对象使用了A类

    class A:
        num = 0
    
        def fun(self):
            pass
    
        def __init__(self,):      #有对象生成就自动执行__init__方法:
            A.fun2()        #自动执行__init__方法会调用fun2方法.
    
        @classmethod    
        def fun2(cls):
            cls.num += 1      #fun2方法使类的静态属性num自增1
    
    c = A()
    b = A()
    d = A()
    a = A()
    print(c.num)                   #打印num静态属性就知道有几个A类的对象
    4

     静态方法

    静态方法:就是一个不依赖类及对象的普通函数

    为什么要用静态方法而不在类外边用普通函数?

    为了保证代码的一致性

    @staticmethod

    class A:
        num = 0
    
        def fun(self):
            pass
    
        def __init__(self,):
            A.fun2()
    
        @staticmethod            #静态方法,和在类外边的普通函数一样  
        def fun2():
            print(6666)
    
    
    A.fun2()
    
    6666

    类属性

    @property

    property是将方法伪装成一个属性,虽然在代码层面上没有提升,但是他会让你的代码看起来更合理一些

    class A:
        def __init__(self,name, weight, heigh):
            self.name = name
            self.weight = weight
            self.heigh = heigh
        @property          #类属性可将函数名变为变量名
        def bmi(self):
            return self.weight / self.heigh **2
    wk = A('wk',65,1.85)
    print(wk.bmi)    #打印时 bmi函数不加()直接返回的的就是对应return的值
    
    18.991964937910883
    class A:
        def __init__(self, name):
            self.name = name
    
        @property        #将a当做变量使用
        def a(self):
            print(1)
    
        @a.setter        #当给a改值时执行这里
        def a(self, value):
            print(value)
            print(2)
    
        @a.deleter       #当删除a值时执行这里
        def a(self):
            print(3)
    c = A('wk')
    c.a
    c.a = 321
    del c.a

    苹果折扣练习 :苹果原始价是8元1斤打7折 球苹果折扣多少钱一斤和重新定价苹果后的折扣价

    class A:
        def __init__(self,name,jiage,zhekou):
            self.name = name
            self.jiage = jiage
            self.zhekou = zhekou
    
        @property
        def pg(self):
           return '%s是%s元' %(self.name, self.jiage*self.zhekou)
        @pg.setter
        def pg(self, xinjia):
            self.jiage = xinjia
    
    a = A('苹果', 8, 0.8)
    
    print(a.pg )
    a.pg = 7
    print(a.pg)
    
    苹果是6.4元
    苹果是5.6000000000000005元

    反射

    isinstance() 判断 一个对象是不是此类或此类的子孙类生成的对象

    class A:
        pass
    class B(A):         #A是B的父类
        pass
    c = B()
    print(isinstance(c, B))   #c 是不是B生成的对象
    print(isinstance(c, A))   #c 是不是A生成的对象
    
    True
    True
    issubclass()一个类是否是令一个类的子类或子孙类
    class A:
        pass
    class B(A):
        pass
    c = B()
    print(issubclass(B, A))    #B是否是A的子类
    
    True

    反射方法

    反射就是:通过 字符串 去操作对象(实例化对象 类, 模块)。 可以通过input交互输入的方式调用类以及对象

    hasattr()       查看是否存在
    getattr()       查看
    setattr()       增加
    delattr()       删除

    对实例化对象的示例

    class A:
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
    b = A('wk', 25)                #对象b
    print(hasattr(b, 'name'))      #判断对象b的变量name是否存在
    print(getattr(b, 'name'))      #查看 对象b的变量name的值
    setattr(b,'xingbie', '')      #增加对象b的变量
    print(b.xingbie)
    delattr(b, 'name')              #删除对象b的变量
    print(b.__dict__)     
    
    True
    wk
    男
    {'age': 25, 'xingbie': ''}

    对类:

    class A:
        name = 'cc'
    
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
    print(hasattr(A, 'name'))      #判断A类的 变量name是否存在
    print(getattr(A, 'name'))          #取A类 变量name的值
    setattr(A, 'xingbie', '')        #增加A类变量xingbie 并赋值男
    print(A.xingbie)
    delattr(A, 'name')                 #删除A类变量name
    print(A.__dict__)

    用input方式调用类的变量

    class A:
        name = 'wk'
    
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
    cc = input('>>>>')
    print(getattr(A, cc))
    
    
    >>>>name
    wk

    对其他模块进行操作

    模块aaa

    #!/usr/bin/env python
    n1 = 'wk'
    
    
    def func():
        print(666)
    
    
    class A:
        name = 'aaa'
    
        def func2(self):
            print('xxxxxx')
    import aaa
    print(getattr(aaa, 'n1'))
    aa = getattr(aaa, 'func')
    aa()
    bb = getattr(aaa, 'A')
    print(bb.name)
    cc = getattr(aaa.A, 'name')
    print(cc)
    getattr(aaa.A, 'func2')(1)
    
    
    wk
    666
    aaa
    aaa
    xxxxxx

     __str__

    如果一个类中定义了__str__方法,那么在打印对象时,默认输出该方法的返回值(默认执行该方法).

    class A :
        def __init__(self):
            pass
        def __str__(self):
            return '654'
    a = A()
    print(a)        打印对象则打印__str__()的返回值, 

    654

    __repr__ 

    在repr对象时返回repr的返回值

    class A:
        name = 'wk'
    
        def __init__(self):
            pass
    
        def __repr__(self):
            return '654'
    
    
    a = A()
    print(repr(a))

    654

    __call__

    对象加()触发__call__方法

    class A:
        name = 'wk'
    
        def __init__(self):
            pass
    
        def __call__(self, *args, **kwarge):
            print(args)
    
    
    a = A()
    a('wk', 'xx', 123)                   #对象加括号触发__call__方法,可以传参

    ('wk', 'xx', 123)

    __item__ 

    对一个对象进行类似于字典的操作,就会触发__item__系列的某个方法.

    item系列:包括__setitem__,__getitem__,__delitem__,

    getitem

    class A:
        def __init__(self, name):
            self.name = name
    
        def __getitem__(self, item):
            print('执行了 此方法')
            print(item)
    
    f = A('wk')
    f['name']            #对象名这样写即触发getitem
    class A:
        def __init__(self, name):
            self.name = name
    
        def __getitem__(self, item):
            print('执行了 此方法')
            print(item)
            return self.__dict__[item]   #可以将对象当字典调用 根据静态变量名找到对象对应的值
    
    f = A('wk')
    print(f['name'])
    
    执行了 此方法
    name
    wk

    setitem

    class A:
        def __init__(self, name):
            self.name = name
        def __setitem__(self, key, value):
            self.key = value
            self.value = key
    
    f = A('wk')
    f['k'] = 123             #对象名这样写触发setitem
    print(f.__dict__) 
    
    {'name': 'wk', 'key': 123, 'value': 'k'}

    deltiem

    class A:
        def __init__(self, name):
            self.name = name
        def __delitem__(self, key):
            print('执行了删除key')
            return self.__dict__.pop(key)
    
    f = A('wk')
    del f['name']               #对象名这样写触发delitem
    print(f.__dict__)
    
    执行了删除key
    {}

    设计模式

    单例模式:让一个类的实例化对象有且只有一个.

    class A:
        __instance = None
    
        def __new__(cls, *args, **kwargs):         
            if cls.__instance is None:                  #第一次进入
                obj = object.__new__(cls)               #借助object创建一个对象 obj
                cls.__instance = obj                    #将第一次创建的对象赋值给了__instance 
            return cls.__instance                       #第二次进入 if cla.__instance 不为空,直接return 第一次的对象
    rea
    = A() rea1 = A() rea2 = A() print(rea, rea1, rea2) <__main__.A object at 0x0000027569695278> <__main__.A object at 0x0000027569695278> <__main__.A object at 0x0000027569695278>

     模块

    模块就是py文件

    1.内置模块 time os random shelve re 等等

    2.拓展模块.大神写的. beautifulsoup iteat

    3.自定义米快

    序列化模块 : json, pickle,shelve

    序列化 将重要的数据转化成可以传输,并且得到后能够反解出来(就是一隔特殊的字符串,能用于网络传输).

    json: 适用于所有语言.

    python        json

    dict             object

    list,tuple     array

    str               string

    int,float      number

    True           true

    False          false

    None          null

    json里的dumps,loads和dump和load  解析和反解,dumps和loads用于网络传输,dump和load用于文件写入

    import json
    
    dic = {'name': '马冬梅', 'age': 25, 'sex': ''}
    ret = json.dumps(dic)      #将dic序列化为json   
    print(ret, type(ret))      
    ret1 = json.dumps(dic, ensure_ascii=False)      #将dic序列化为人能看懂的json
    print(ret1, type(ret))
    rett = json.loads(ret)      #将序列化的json反解出来
    print(rett)
    import json
    f = open('json', 'w')
    dic = {'k1': 1, 'k2': 2, 'k3': 3}
    json.dump(dic,f,ensure_ascii=False)        #将一个字典传入到一个写入的文件句柄
    f.close()

    json与普通字符串的区别

    import json
    
    dic = {'name': '马冬梅', 'age': 25, 'sex': ''}
    ret = json.dumps(dic, ensure_ascii=False)
    print(dic)
    print(ret)
    
    {'name': '马冬梅', 'age': 25, 'sex': ''}         #普通字符串的是单引号
    {"name": "马冬梅", "age": 25, "sex": ""}         #json字符串的是双引号                                                                                                                                  

    pickle 只用于Python语言之间的传输,包含所有Python支持的所有数据类型  和json用法基本一致

    dumps和loads 传输用法

    import pickle
    
    dic = {'name': '马冬梅', 'age': 25, 'sex': ''}
    ret = pickle.dumps(dic)            #与json用法基本一致
    set = pickle.loads(ret)
    print(ret)
    print(set)
    
    b'x80x03}qx00(Xx04x00x00x00nameqx01X	x00x00x00xe9xa9xacxe5x86xacxe6xa2x85qx02Xx03x00x00x00ageqx03Kx19Xx03x00x00x00sexqx04Xx03x00x00x00xe5xa5xb3qx05u.'
    {'name': '马冬梅', 'age': 25, 'sex': ''}

     dump和load 文件写入用法 (这个不仅可以写常规的数据,还可以将对象写入,)

    import pickle
    class A:
        name = 'wk'
        def func(self):
            print(666)
    ww = A()
    f = open("cc",'wb')
    pickle.dump(ww,f)
    
    f = open('cc','rb')
    ret = pickle.load(f)
    print(ret.name)
    ret.func()
    f.close()
    
    wk
    666

     

    random随机模块

    import random
    
    print(random.random())      # 随机大于0且小于1之间的小数
    print(random.uniform(1, 3))  # 随机指定范围之间的小数
    print(random.randint(1, 5))  # 随机指定范围之间的整数
    print(random.randrange(1, 10, 2))  # 随机指定范围之间的奇数
    print(random.choice([1, 23, [4, 5]]))  # 随机选择一个返回,返回1或23或[4,5]
    print(random.sample([1, 23, [4, 5], 'wk'], 2))  # 随机选择两个组成一个列表返回
    
    item = [1, 3, 5, 7, 9]
    random.shuffle(item)           #打乱顺序
    print(item)
    
    0.24827130573087497 1.3810108843857392 4 5 [4, 5] [1, 23] [3, 7, 1, 5, 9]

    利用random模块写一个生成随机数的函数

    import random
    
    
    def suij():
        code = ''
        for i in range(5):
            num = str(random.randint(0, 9))   # 0-9的数字
            zim = chr(random.randint(97, 122))  # A-Z的大写字母
            ZIM = chr(random.randint(65, 90))  # a-z的小写字母
            add = random.choice([num, zim, ZIM])  # 随机选取其中一个
            code += add  # 每次加1循环5次
        return code
    
    
    print(suij())
    
    82TqP

    shelve 持久化存储

    import shelve      
    s = shelve.open('ccc')          #打开一个持久化存储文件
    s['name'] = 'wk'                 #将数据以键值的形式存入到文件里
    print(s['name'])                
    s.close()
    
    
    #在其它脚本里使用
    import shelve
    s = shelve.open('jay')
    print(s['name'])
  • 相关阅读:
    2021 发工资咯:)
    HDU-2021
    HDU-2020
    HDU-2019
    HDU-2018
    HDU-2017
    HDU-2016
    HDU-2015
    HDU-2014
    HDU-2013
  • 原文地址:https://www.cnblogs.com/ywrj/p/10170989.html
Copyright © 2020-2023  润新知