zoukankan      html  css  js  c++  java
  • 四大器

    四大器

    目录

    一、迭代器

    迭代器:迭代取值的工具 ——(用__iter__生成迭代器对象)

    优点:1.不依赖与索引取值

       2.内存中只占一份空间,不会内存溢出,节约空间,运行效率更高(执行一次__next__取值一次,而不是一次全部取值)

    缺点:1.不能获取指定的元素

       2.只能依次往后取值

    1.迭代协议

    class MyIter:
        """num传入 用来指定迭代次数 """
    
        def __init__(self, num):
            self.num = num
            self.c = 0
            
        # 迭代
        def __iter__(self):
            return self
        
        # 取值
        def __next__(self):
            self.c += 1
            if self.c <= self.num:
                return "jeff"
            else:
                raise StopIteration
    
    # 循环取值
    for i in MyIter(10):
        print(i)
    
    #结果:打印10遍jeff
    

    2.一个简单的迭代器:

    k = [1, 2, 3]
    # 生成迭代器对象
    k1 = k.__iter__()
    #迭代器取值,调用__next__()
    print(k1.__next__())
    print(k1.__next__())
    print(k1.__next__())
    

    img

    3.迭代异常处理(迭代完了,没有了,try)

    k = [1,2,3]
    k1 = k.__iter__()while True:
        try:
            print(k1.__next__())
        except StopIteration:
            print("没有了")
            break
    

    img

    二、生成器

    优点:节约内存,不会内存溢出

    生成器:使用yield自定义的迭代器叫生成器

    yield:

    1.后面不跟值,默认返回None,可以返回多个值

    2.帮你将函数的运行状态暂停住

    3.可以返回值,多个也可以

    yield与return的区别:

    1.yield配合迭代器使用__next__一个一个取值,return一次性全取

    2.yield可以返回多次值,return返回一次立即结束函数

    3.yield可以接受外部传入的值

    def func():
        print("first")
        yield 1, 2, 3  # 函数内如果有yield,执行函数时不会执行函数代码
    
    k = func()  # 将函数转化为迭代器
    k2 = k.__next__()  # 取值
    print(k2)
    

    img

    要一次,取一次值

    def func():
        print('第一次')
        yield 1, 2, 3
        print('第二次')
        yield 2
        print('第三次')
        yield 3
        print('第四次')
        yield
        yield
    k = func()  # 转化为迭代器
    # k1 = k.__iter__()  # 这里不用生成迭代对象,函数自身可被迭代
    print(k.__next__())
    print(k.__next__())
    print(k.__next__())
    print(k.__next__())
    

    img

    三、装饰器

    定义:不改变函数的源代码、调用方式,添加新的功能

    1.无参模板(二层)

    from functools import wraps   #  语法糖
    
    
    def outter(func):   # 固定搭配
        @wraps(func)  # 固定搭配   语法糖
        def inner(*args, **kwargs):   # 固定搭配
            
            # 装饰前做的事
            return func(*args, **kwargs)  # 固定搭配
            # 装饰后做的事
        
        return inner  # 固定搭配
    

    例子:给lookup添加登录认证的功能

    user_info = {
        'user':None
    }
    
    def login():
    
        user = input('请输入用户名>>>:')
        passwd = input('请输入密码>>>:')
        passwd_d = input('请再次输入密码>>>:')
        if passwd == passwd_d:
            user_info['user'] = user
            print('登录成功')
        else:
            print('登录失败')
    
    
    def register():
    
        user = input('请输入用户名>>>:')
        passwd = input('请输入密码>>>:')
        passwd_d = input('请再次输入密码>>>:')
        if passwd == passwd_d:
            with open(r'user', 'w')as f:
                f.write(user)
                f.write(passwd)
        else:
            print('重新输入')
    
    # 装饰器
    def outter(func):
    
        def inner(*args, **kwargs):
            if user_info['user']:
                print('hello')
                return func(*args, **kwargs)
            else:
                print('请先登录')
                login()  # 添加login的功能
        return inner
    
    
    @outter
    def lookup():
        with open(r'user','r')as f:
            print(f.read())
    
    
    
    def run():
        while True:
            print('''
    请选择你的功能>>>:
    1.注册
    2.登录
    3.查看信息''')
            choice = input('>>>:')
            if not choice.isdigit():
                print('请输入数字')
                continue
    
            msg = {'1': register,
                   '2': login,
                   '3': lookup}
            msg[choice]()
    
    run()
    

    2.有参模板(三层)

    # 有参模板
    from functools import wraps
    
    def wrappers(params1,params2,params3):
        def outter(func):
            @wraps(func)
            def inner(*args, **kwargs):
                
                # 装饰前做的事
                    return func(*args, **kwargs)
                # 装饰后做的事
                
            return inner
        return outter
    

    四、内置装饰器(绑定方法)

    1.@property内置装饰器

    夺命三问:
        1.什么是property?
            是一个python内置的装饰器,可以装饰在"类内部的方法"上。
            可以将该方法调用方式由 ----> 对象.方法() ---> 对象.方法
    
        2.为什么用property?
            PS: 在某些场景下,调用的方法只是用来获取计算后的某个值。
            PS: 必须通过 对象.方法() 方式调用,让该方法看起来像执行函数。
    
            让名词的方法,调用时更为合理。
            目的是为了,迷惑调用者,调用的方法误以为是 属性。
    

    装饰器:为了调用方式一致,方便使用者
    @property首先创建一个age对象,所以@setter、@deleter要加函数名
    :这里的age是装饰方法的名称

    @property(获取私有) :把一个方法伪装成普通属性,通常函数名和属性名保持一致(方便使用者调用)
    @函数名.setter(修改私有):函数名和属性名保持一致
    @函数名.deleter(控制删除):

    class A:
        def __init__(self, name, age):
            self.name = name
            self.__age = age
    
        @property   # 获取属性时,触发下面
        # 获取伪装成普通属性,通常函数名伪装成属性名
        def age(self):
            return self.__age
    
        @age.setter  # 修改属性时,触发下面
        def age(self, new_age):
            self.__age = new_age
            print('修改成功')
    
        @age.deleter  # 删除属性时,触发下面
        def age(self):
            del self.__age
            print('删除成功,已经没有了')
    # 查看
    jeff = A('jeff', 50)
    print(jeff.age)  #  50
    
    # 修改
    jeff.age = '100'
    print(jeff.age)  # 修改成功   100
    
    # 删除
    del jeff.age
    print(jeff.age)  # 报错,删除成功,已经没有了
    

    绑定方法

    classmethod:
        是一个装饰器,给在类内部定义方法中装饰,将类内部的方法变为 “类的绑定方法”。
    
    staticmethod:
        翻译: 静态方法
        是一个装饰器,给在类内部定义方法中装饰,将类内部的方法变为 “非绑定方法”。
    
    - 对象的绑定方法:
        - 由对象来调用,由谁来调用,会将谁(对象)当做第一个参数传入。
    
    - 类的绑定方法:
        - 由类来调用,由谁来调用,会将谁(类)当做第一个参数传入。
    
    - 非绑定方法:
        - 可以由对象或类来调用,谁来调用都是一个普通方法(普通函数),方法需要传入几个参数,就得传入几个。
    

    1.对象绑定方法

    没有被任何装饰器装饰的方法,为对象量身定制

    对象.方法(),自动将对象单座第一个参数传入self

    class OldboyStudent:
        school = 'oldboy'
    
        def __init__(self, name, age, gender):
            self.name = name
            self.age = age
            self.sex = gender
    
        def choose_course(self):
            print(f'{self.name} choosing course')
    
        def func(self):
            print('from func')
          
    stu1 = OldboyStudent('nick', 18, 'male')
    stu2 = OldboyStudent('sean', 17, 'male')
    stu3 = OldboyStudent('tank', 19, 'female')
    
    print(stu1.name)   # nick
    print(stu1.school)   # oldboy
    

    2.类的绑定方法@classmethod

    classmethod:
        是一个装饰器,给在类内部定义方法中装饰,将类内部的方法变为 “类的绑定方法”。
    

    例子:

    class Dog():
        def eat(self):
            print('狗狗吃饭饭。。。')
    
    class Pig():
        @classmethod  # 将此方法对象绑定
        def eat(self):
            print('猪猪看电视。。。')
    
    # 对象绑定方法,需要实例化出一个对象
    keji = Dog()
    keji.eat()
    
    # 类绑定方法,不需要对象,直接通过类
    zhu = Pig.eat()
    

    例子2:进阶高级

    class DB:
        __data = 'jeff is very handsome!!!'
        def __init__(self, user, pwd, role):
            self.user = user
            self.pwd = pwd
            self.role = role
            
        # 查看数据方法
        @classmethod  # 类绑定
        def check_db(cls, user, pwd, role):  # cls --》指的是类
            # 在类方法内部调用类产生一个实例 ---》 对象
            obj = cls(user, pwd, role)    # 再类的内部实例化出一个对象,供内部使用
    
            # 1.查看数据前,必须要通过校验
            if obj.user == 'tank' and obj.pwd == '123' and obj.role == 'admin':
                print('检验通过..')
                print(cls.__data)
                return cls.__data
            
    # 类绑定方法了
    DB.check_db('tank', '123', 'admin')
    #  结果:
    检验通过..
    jeff is very handsome!!!
    

    3.非绑定方法@staticmethod

    非绑定方法:
        - 可以由对象或类来调用,谁来调用都是一个普通方法(普通函数),方法需要传入几个参数,就得传入几个。
    1.不用非绑定方法,打印的是func函数的地址
    class Foo:
        def func(res):
            print(res)
    obj = Foo()
    obj.func()
    #  <__main__.Foo object at 0x000001FF9F5D82E8>
    
    2.对象调用非绑定方法
    class Foo:
        @staticmethod
        def func(res):
            print(res)
    # 产生了obj对象
    obj = Foo()
    obj.func(123)  # 123
    
    3.类直接调用非绑定方法
    class Foo:
        @staticmethod
        def func(res):
            print(res)
    Foo.func(1234)
    #  1234
    
  • 相关阅读:
    CF733F
    P4826
    洛谷P2687 & P1108
    CF42A
    洛谷P1858
    CF1428C
    洛谷P4981
    树形DP
    背包六讲(也不知道为啥就是六个 $QwQ$)
    2020
  • 原文地址:https://www.cnblogs.com/WQ577098649/p/11887429.html
Copyright © 2011-2022 走看看