zoukankan      html  css  js  c++  java
  • python学习第24天

    一.装饰器

    装饰器:为原函数扩展新功能,用新功能去替代旧功能

    作用: 在不改变原有代码的基础上,实现功能上的扩展

    符号: @(语法糖)

    (1) 装饰器的基本用法

    def kuozhan(func):
       def newfunc():
          print("厕所前,蓬头垢面")
          func()
          print("厕所后,精神气爽")
       return newfunc
    
    def func():
       print("我叫高富帅")
       
    func = kuozhan(func) # func = newfunc  <=>   func() = newfunc()
    func()
    

    (2)@符号的作用

    1)可以自动把@符号下面的函数当成参数传递给装饰器

    2)把新函数进行返回,让新函数去替换旧函数,以实现功能的扩展

         # func = newfunc  <=>   func() = newfunc()
    
    def kuozhan(func):
       def newfunc():
          print("厕所前,蓬头垢面")
          func()
          print("厕所后,精神气爽")
       return newfunc
    
    @kuozhan
    def func():
       print("我叫高富帅")
    
    func() 
    

    (3)装饰器的嵌套

    def kuozhan1(func):
       def newfunc():
          print("厕所前,人模狗样1")
          func()
          print("厕所后,牛头马面2")
       return newfunc
       
    def kuozhan2(func):
       def newfunc():
          print("厕所前,洗洗手3")
          func()
          print("厕所后,簌簌口4")
       return newfunc
    
    @kuozhan2
    @kuozhan1
    def func():
       print("我是白富美5")
    
    func()
    

    (4)用装饰器修饰带有参数的函数

    扩展的新功能和原函数的功能,在参数和返回值上,要保持一致性

    def kuozhan(func):
       def newfunc(who,where):
          print("厕所前,萎靡不振")
          func(who,where)
          print("厕所后,兽性大发")
       return newfunc
    
    @kuozhan
    def func(who,where):
       print("{who}在{where}解手".format(who=who,where=where))
    
    func("朱胜","电影院")
    

    (5)用装饰器修饰带有参数返回值的函数

    def kuozhan(func):
       def newfunc(*args,**kwargs): # 函数的定义处, *号的打包操作
          print("厕所前,饥肠辘辘")
          lst = func(*args,**kwargs) # 函数的调用处,*号解包操作
          print("厕所后,酒足饭饱")
          return lst
       return newfunc
    
    
    @kuozhan
    def func(*args,**kwargs):
       dic = {"wz":"王振" , "wyl":"尉翼麟" , "yc":"云超"}
       lst = []
       strvar = ""
       
       # 遍历拉屎的地点
       for i in args:
          print("拉屎的地方在", i )
       
       # print(args)
       # print(kwargs)
       
       """
       # 正常写法
       for k,v in kwargs.items(): 
          if k in dic:
             strvar = dic[k] + "留下" + v + "黄金"
             lst.append(strvar)
       return lst
       """
       # 推导式
       return [dic[k] + "留下" + v + "黄金" for k,v in kwargs.items() if k in dic]
       
       # "谁留下多少黄金"
       
    res = func("电影院","水里",wz="18斤",wyl="18吨",yc="18克",zzz = "19k")
    print(res)
    

    (6)用类装饰器来扩展原函数

    class Kuozhan():
    
       def __call__(self,func):
          return self.kuozhan2(func)
    
       
       def kuozhan1(func):
          def newfunc():
             print("厕所前,老实巴交")
             func()
             print("厕所后,咋咋呼呼")
          return newfunc
          
          
       def kuozhan2(self,func):
          def newfunc():
             print("厕所前,唯唯诺诺")
             func()
             print("厕所后,重拳出击")
          return newfunc
          
    """
    # 方法一
    @Kuozhan.kuozhan1
    def func():
       print("厕所进行时...")
    
    func()
    """
    
    # 方法二
    """
    @Kuozhan()  => @obj<=>对象 => obj(func) <=> 把对象当成函数进行使用了,自动触发__call__魔术方法. 
    =>  把新函数newfunc 返回了  => @ 发动第二个技能,将新函数去替换旧函数, func = newfunc
    func()  <==>  newfunc()
    
    
    def func():
       print("厕所进行时...")
    
    func()
    """
    @Kuozhan()
    def func():
       print("厕所进行时...")
    
    func()
    

    (7)带有参数的函数装饰器

    def outer(num):
       def kuozhan(func):
          def newfunc1(self):
             print("厕所前,干净整齐")
             res = func(self)
             print("厕所后,臭气熏天")
             return res
             
          def newfunc2(self):
             print("厕所前,饥肠辘辘")
             res = func(self)
             print("厕所后,满口雌黄")
             return res
    
          if num == 1 :
             return newfunc1          
          elif num == 2:
             return newfunc2
          elif num == 3:
             # 把方法变成属性
             return "我是男性"        
             
       return kuozhan
    
    
    class MyClass():
       @outer(1) # outer(1) => kuozhan  ,   @kuozhan <=> kuozhan(func1) [@符号第一次发动技能] <=> func1 = newfunc1 [@符号第二次发动技能]
       def func1(self):
          print("先前一小步,文明一大步")
          
       @outer(2) # outer(1) => kuozhan  ,   @kuozhan <=> kuozhan(func2) [@符号第一次发动技能] <=> func2 = newfunc2 [@符号第二次发动技能]
       def func2(self):
          print("来也匆匆,去也匆匆")
    
       @outer(3) # outer(3) => kuozhan  ,   @kuozhan <=> kuozhan(func3) [@符号第一次发动技能] <=> func3 = "我是男性"
       def func3():
          print("尿到外面,说明你短!")
    
    obj = MyClass()
    obj.func1() # func1 <=> newfunc1
    obj.func2()
    # 把方法变成属性
    print(obj.func3)
    

    (8)带有参数的类装饰器

    """
    如果参数是1,就为当前类添加成员属性和方法
    如果参数是2,就把原方法run变成属性
    """
    class Kuozhan():
       ad = "贵族茅房,每小时100元,贵族茅房,欢迎您来,欢迎您再来"
       def __init__(self,num):
          self.num = num
          
       def __call__(self,cls):
          if self.num == 1:
             return self.newfunc1(cls)
          elif self.num == 2:
             return self.newfunc2(cls)
             
       def money(self):
          print("茅中贵族,百岁山")
          
       # 参数为1的情况
       def newfunc1(self,cls):
          def newfunc():
             # 为当前cls这个类,添加属性
             cls.ad = Kuozhan.ad
             # 为当前cls这个类,添加方法
             cls.money = Kuozhan.money
             return cls()  # 对象
          return newfunc
          
       # 参数为2的情况
       def newfunc2(self,cls):
          def newfunc():
             if "run" in cls.__dict__:
                # 调用类中的方法,拿到返回值
                res = cls.run()
                # 把返回值重新赋值给run属性.后者覆盖了前者,方法变成了属性
                cls.run = res
                return cls()
                
          return newfunc
       
    # obj = Kuozhan(1)
    
    """
    # @obj  [@符号第一次发动技能] <=> obj(MyClass) 把对象当成函数使用了,触发__call__魔术方法
    self.newfunc1(cls) <=> return newfunc 
    =>  [@符号第二次发动技能]  将新函数替换旧函数 MyClass = newfunc  
    obj = MyClass()  <=> newfunc() => cls() => obj对象
    """
    
    # 情况一
    """
    @Kuozhan(1) 
    class MyClass():
       def run():
          return "亢龙有悔"
    
    obj = MyClass()
    print(obj.ad)
    obj.money()
    """
    
    print("<=============>")
    """
    # @obj  [@符号第一次发动技能] <=> obj(MyClass) 把对象当成函数使用了,触发__call__魔术方法
    self.newfunc2(cls) <=> return newfunc 
    =>  [@符号第二次发动技能]  将新函数替换旧函数 MyClass = newfunc  
    obj = MyClass()  <=> newfunc() => cls() => obj对象
    """
    # 情况二
    @Kuozhan(2) 
    class MyClass():
       def run():
          return "亢龙有悔"
    
    obj = MyClass()
    print(obj.run) # 亢龙有悔
    
    """
    obj = MyClass() 的解释:
    # 第一部分,定义一个类
    class Ceshi():
       c = 100
       
    obj = Ceshi()
    print(obj.c)
    
    # 第二部分,定义两个函数
    def func22():
       print(111)
    
    def func(cls):
       cls.aabbcc = 200
       obj = cls()
       return obj
       
    # 第三部分,把类当成参数传递给func,类在func函数中形成一个独立的副本
    obj = func(Ceshi)
    
    # 第四部分,把这个类做替换,变成函数,那么现在在全局空间的Ceshi已经变成了函数,不再是类
    Ceshi = func22
    
    # 第五部分,调用局部空间obj,还是可以得到原来类中的成员属性和方法;
    print(obj.c)
    print(obj.aabbcc)
    
    """
    

    二.面向对象中的方法

    普通方法:  可以有参数,或者无参数,当场正常的函数调用
    绑定方法:  (1) 绑定到对象(自动传递参数为对象) (2) 绑定到类(自动传递参数为类)
    静态方法:  无论是对象还是类,都可以调用,不会默认传递任何参数
    
    class Dog():
       name = "旺财"
       
       # 普通方法
       def jiao():
          print("小狗哇哇哇的叫唤")
          
       # 绑定方法(对象)
       def eat(self):
          print("小狗喜欢吃骨头")
          
       # 绑定方法(类)
       @classmethod
       def tail(cls):
          print(cls)
          print("小狗看到主任喜欢摇尾巴")
          
       #静态方法
       @staticmethod
       def jump(num):
          print("小狗喜欢接飞盘")
    
    obj = Dog()
    # 普通方法 (无参方法只能类调用)
    # obj.jiao() error
    Dog.jiao()
    
    # 绑定方法 (一般用对象调用)
    obj.eat()  #(推荐)
    Dog.eat(12356)
    
    # 绑定方法(类) 
    """系统自己把类当成参数进行传递"""
    Dog.tail() #(推荐)
    obj.tail()
    
    # 静态方法 (不会默认传递任何参数,如果有参数,当成普通方法调用即可.)
    obj.jump(1)
    Dog.jump(2)
    
    ###  在类外,为对象添加成员方法,默认皆是静态方法.
    obj.func = lambda  : print(123)
    obj.func()
    

    绑定方法(类) : @classmethod

    静态方法: @staticmethod

    1.1property装饰器

    property 可以把方法变成属性使用

    作用:控制属性的获取,设置,删除操作

    变相增加成员的安全性,可以通过自定义逻辑对成员进行控制

    自动触发:要求是同一个名字

    获取: @property

    设置:@属性名.setter

    删除:@属性名.deleter

    # 方法一
    class MyClass():
       def __init__(self,name):
          self.name = name
          
       @property
       def username(self):
          return self.name
          # pass
          
       @username.setter
       def username(self,val):
          print(112233)
          val = "朴仁猛"
          self.name = val
          # pass
       
       @username.deleter
       def username(self):
          # 如果发现有删除行为,可以在这个方法中拒绝删除
          pass
          #del self.name
       
          
    obj = MyClass("小芳")
    
    # 获取属性 (自动触发获取方法 @property)
    # print(obj.username())
    print(obj.username)
    
    
    # 设置属性 (自动触发设置方法) val形参自动接收设置的值
    obj.username = "朴仁猛"
    print(obj.username)
    
    # 删除属性
    del obj.username
    # print(obj.username) error
    
    # 方法二
    class MyClass():
       def __init__(self,name):
          self.name = name
          
       # 获取
       def get_username(self):
          return self.name
    
          
       # 设置
       def set_username(self,val):
          # val = "朴仁猛"
          self.name = val
    
       
       # 删除
       def del_username(self):
          # 如果发现有删除行为,可以在这个方法中拒绝删除
          del self.name
          
       # 顺序必须按照  获取 -> 设置 -> 删除 的参数进行传递
       username = property(get_username,set_username,del_username)
          
    obj = MyClass("朴飘乐")
    # 获取
    print(obj.username)
    # 设置
    obj.username = "朴一生"   
    print(obj.username)
    # 删除
    del obj.username
    print(obj.username) #error 被删掉了
    

    三.反射

    概念:通过字符串去操作类,对象或者模块当中的成员(属性,方法)

    class Man():
       pass
    
    class Woman():
       pass
    
    class Children(Man,Woman):
    
       """
       成员属性: eye 
       成员方法: skylight moonread __makebaby
       完成的功能: 描述小孩天生神力.
       """
    
       eye = "血轮眼"
       
       def skylight(self):
          print("一下生,直接使用天照,让世界变得混乱")
          
       def moonread(self,func):
          print("一下生,使出了武功绝学,月读,世界都黑暗里~")
          print(func.__name__ , type(  func.__name__  )) # earth_boom
       
       def __makebaby(self):
          print("这一手招数,只能我自己用")
    
    obj = Children()
    

    (1)反射类对象中的成员

    hasatter() 检测对象/类是否有指定的成员

    # 对象
    res = hasattr(obj,"eye")
    print(res)
    
    # 类
    res = hasattr(Children,"skylight")
    res = hasattr(Children,"__makebaby")
    print(res)
    

    getatter() 获取对象/类成员的值

    # 对象
    func = getattr(obj,"skylight")
    func()  # 通过对象反射出来的方法是绑定方法
    
    # 类
    func = getattr(Children,"skylight")
    func(1) # 通过类反射出来的是一个普通方法
    
    # 当类对象中的成员不存在时,可以设置默认值(第三个参数是默认值参数)
    func = getattr(obj,"moonread123345","对不起,该成员不存在")
    print(func)
    # 综合案例
    """
    strvar = input("请输入你要调用的方法")
    if hasattr(obj,strvar):
    	func = getattr(obj,strvar)
    	func()
    """
    

    setatter() 设置对象/类成员的值

    # 对象
    setattr(obj,"eye","白眼")
    print(obj.eye)
    # 类
    setattr(Children,"tcut",lambda  : print("小孩一下生就能用雷切战术"))
    Children.tcut()
    # obj.tcut() #tcut 是一个无参普通方法,只能是类来调用;
    

    delatter() 删除对象/类成员的值

    # 对象
    delattr(obj,"eye")
    print(obj.eye)
    
    # 类
    delattr(Children,"eye")
    # print(obj.eye)
    

    (2)反射模块中的成员

    sys.modules 返回一个系统的字典,加载系统模块展现出来

    import sys 
    print(sys.modules)
    
    """
    {
    'builtins': <module 'builtins' (built-in)>, 
    'sys': <module 'sys' (built-in)>, 
    '_frozen_importlib': <module '_frozen_importlib' (frozen)>, 
    '_imp': <module '_imp' (built-in)>, 
    '_warnings': <module '_warnings' (built-in)>, 
    '_thread': <module '_thread' (built-in)>, '_weakref': <module '_weakref' (built-in)>, '_frozen_importlib_external': <module '_frozen_importlib_external' (frozen)>, '_io': <module 'io' (built-in)>, 'marshal': <module 'marshal' (built-in)>, 'nt': <module 'nt' (built-in)>, 'winreg': <module 'winreg' (built-in)>, 'zipimport': <module 'zipimport' (built-in)>, 'encodings': <module 'encodings' from 'C:\Users\wangwen\AppData\Local\Programs\Python\Python36\lib\encodings\__init__.py'>, 'codecs': <module 'codecs' from 'C:\Users\wangwen\AppData\Local\Programs\Python\Python36\lib\codecs.py'>, '_codecs': <module '_codecs' (built-in)>, 'encodings.aliases': <module 'encodings.aliases' from 'C:\Users\wangwen\AppData\Local\Programs\Python\Python36\lib\encodings\aliases.py'>, 
    'encodings.utf_8': <module 'encodings.utf_8' from 'C:\Users\wangwen\AppData\Local\Programs\Python\Python36\lib\encodings\utf_8.py'>, '_signal': <module '_signal' (built-in)>, 
    '__main__': <module '__main__' from 'E:/python30/day24/1.py'>, 'encodings.latin_1': <module 'encodings.latin_1' from 'C:\Users\wangwen\AppData\Local\Programs\Python\Python36\lib\encodings\latin_1.py'>, 'io': <module 'io' from 'C:\Users\wangwen\AppData\Local\Programs\Python\Python36\lib\io.py'>, 'abc': <module 'abc' from 'C:\Users\wangwen\AppData\Local\Programs\Python\Python36\lib\abc.py'>, '_weakrefset': <module '_weakrefset' from 'C:\Users\wangwen\AppData\Local\Programs\Python\Python36\lib\_weakrefset.py'>, 'site': <module 'site' from 'C:\Users\wangwen\AppData\Local\Programs\Python\Python36\lib\site.py'>, 'os': <module 'os' from 'C:\Users\wangwen\AppData\Local\Programs\Python\Python36\lib\os.py'>, 'errno': <module 'errno' (built-in)>, 'stat': <module 'stat' from 'C:\Users\wangwen\AppData\Local\Programs\Python\Python36\lib\stat.py'>, 
    '_stat': <module '_stat' (built-in)>, 'ntpath': <module 'ntpath' from 'C:\Users\wangwen\AppData\Local\Programs\Python\Python36\lib\ntpath.py'>, 'genericpath': <module 'genericpath' from 'C:\Users\wangwen\AppData\Local\Programs\Python\Python36\lib\genericpath.py'>, 'os.path': <module 'ntpath' from 'C:\Users\wangwen\AppData\Local\Programs\Python\Python36\lib\ntpath.py'>, '_collections_abc': <module '_collections_abc' from 'C:\Users\wangwen\AppData\Local\Programs\Python\Python36\lib\_collections_abc.py'>, '_sitebuiltins': <module '_sitebuiltins' from 'C:\Users\wangwen\AppData\Local\Programs\Python\Python36\lib\_sitebuiltins.py'>, '_bootlocale': <module '_bootlocale' from 'C:\Users\wangwen\AppData\Local\Programs\Python\Python36\lib\_bootlocale.py'>, '_locale': <module '_locale' (built-in)>, 'encodings.gbk': <module 'encodings.gbk' from 'C:\Users\wangwen\AppData\Local\Programs\Python\Python36\lib\encodings\gbk.py'>, '_codecs_cn': <module '_codecs_cn' (built-in)>, '_multibytecodec': <module '_multibytecodec' (built-in)>, 'sysconfig': <module 'sysconfig' from 'C:\Users\wangwen\AppData\Local\Programs\Python\Python36\lib\sysconfig.py'>, 
    'encodings.cp437': <module 'encodings.cp437' from 'C:\Users\wangwen\AppData\Local\Programs\Python\Python36\lib\encodings\cp437.py'>}
    """
    # 获取本模块的对象
    print(sys.modules["__main__"])
    selfmodule = sys.modules["__main__"]
    
    def func1():
       print("我是func1方法")
    
    def func2():
       print("我是func2方法")
    
    def func3():
       print("我是func3方法")
    
    # 综合案例
    while True:
       strvar = input("请输入你要反射的方法")
       if hasattr(selfmodule,strvar):
          func = getattr(selfmodule,strvar)
          func()
       elif strvar.upper() == "Q":
          break
       else:
          print("没有这个方法")
    
  • 相关阅读:
    数据库之多表查询
    Sublime 的中文乱码问题
    MySQL连接问题浅析
    对国产操作系统发展的一些思考
    Azure PowerShell 1.0.0以上版本在中国Azure使用的注意事项
    Windows Azure移动终端云服务管理(公测版)
    12月2日,上海Cloud Foundry Summit, Azure Cloud Foundry 团队期待和你见面!
    Android项目:proguard混淆第三方jar.
    MySQL Database on Azure
    物联网操作系统HelloX已成功移植到MinnowBoard MAX开发板上
  • 原文地址:https://www.cnblogs.com/yunchao-520/p/13028743.html
Copyright © 2011-2022 走看看