1.变量作用域

全局变量和局部变量

  1. #变量是有作用域的,分为全局变量和局部变量
  2. num = 100 #这是全局变量
  3. def change():
  4. """
  5. 查看变量作用域
  6. """
  7. num = 30 #这是局部变量
  8. print("change函数内部的,局部变量:",num)
  9. change()
  10. print("全局变量:",num)
  11. """
  12. change内部的变量: 30
  13. 全局变量: 100
  14. """

全局变量和局部变量互相转换

  1. #global:局部变量转换为全局变量
  2. num = 100
  3. def change():
  4. """
  5. 修改全局变量内容
  6. """
  7. global num
  8. num = 30
  9. print("change内部的变量:",num)
  10. change()
  11. print("全局变量:",num)
  12. """
  13. change内部的变量: 30
  14. 全局变量: 30
  15. """
  16.  
  17. #nonlocal:全局变量转换为局部变量 【只能使用在闭包中】
  18. #全局作用域
  19. x = 0
  20.  
  21. def outter():
  22. #函数作用域
  23. x = 1
  24. def inner():
  25. #局部作用域
  26. nonlocal x
  27. x = 2
  28. print("inner:",x)
  29. inner()
  30. print("outter:", x)
  31.  
  32. f = outter()
  33. print("global:",x)
  34. """
  35. inner: 2
  36. outter: 1 ---- >2
  37. global: 0
  38. """
  39.  
  40. #总结:当变量重名的前提下,修改内部函数的局部作用域为函数作用域,nonlocal扩大作用域

2.闭包

  1. def p(count):
  2. def out(data):
  3. nonlocal count
  4. count += 1
  5. return "第{}次输出数据:{}".format(count,data)
  6. return out
  7. oa = p(0)
  8. print(oa("tom"))
  9. print(oa("hello"))
  10. print(oa("ok"))
  11. """
  12. 第1次输出数据:tom
  13. 第2次输出数据:hello
  14. 第3次输出数据:ok
  15. """

lambda与闭包

  1. #lambda实现闭包
  2. def add(n1):
  3. return lambda n2: n1 + n2
  4. hello = add(100)
  5. print(hello(200))

3.装饰器

  1. # 方法四:定义一个装饰器接收操作函数,是由python传递
  2. def log_logging(func):
  3. def wrapper(*args, **kwargs):
  4. #获取包装函数的名称
  5. print("方法四:这是装饰器的日志方法,当前函数为:{}".format(func.__name__))
  6. return func(*args, **kwargs)
  7. return wrapper # 返回装饰器函数,就是闭包
  8. class Message:
  9. @log_logging #方法四
  10. def print_title(self):
  11. print("方法一:这是print方法直接输出的日志")
  12. logging()
  13. log()
  14.  
  15. #方法二:定义一个日志函数
  16. def logging():
  17. print("方法二:这是使用logging函数,输出的日志!!")
  18.  
  19. #方法三:使用inspet模块方法,获取方法名称
  20. def log():
  21. import inspect
  22. res = inspect.stack()[1][3]
  23. print("方法三:这是使用inspect模块,输出的日志!当前方法为:{}".format(res))
  24.  
  25. if __name__ == '__main__':
  26. m = Message()
  27. m.print_title()

完整的日志装饰器

  1. def log_logging(level="info"):
  2. def wrapper(func):
  3. def inner(*args, **kwargs):
  4. #获取包装函数的名称
  5. print("【logging-{}】的日志,当前函数为:{}".format(level,func.__name__))
  6. return func(*args, **kwargs)
  7. return inner # 返回装饰器函数,就是闭包
  8. return wrapper
  9. class Message:
  10. @log_logging(level="DEBUG") # 设置参数
  11. def print_title(self):
  12. print("正在使用print——title方法!")
  13.  
  14. if __name__ == '__main__':
  15. m = Message()
  16. m.print_title()

基于类定义实现的装饰器

  1. # 使用call方法
  2.  
  3. class logging:
  4. def __init__(self, level = "INFO"):
  5. self.__level = level
  6. def __call__(self, func):
  7. def inner(*args, **kwargs):
  8. # 获取包装函数的名称
  9. print("【logging-{}】的日志,当前函数为:{}".format(self.__level, func.__name__))
  10. return func(*args, **kwargs)
  11.  
  12. return inner # 返回装饰器函数,就是闭包
  13. class Message:
  14. @logging(level="DEBUG")
  15. def print_info(self):
  16. print("正在使用print_info的方法。")
  17.  
  18. if __name__ == '__main__':
  19. m = Message()
  20. m.print_info()
    """

【logging-DEBUG】的日志,当前函数为:print_info
正在使用print_info的方法。

"""

  1.  

wrapt模块

  1. #wrapt减少嵌套层数
  2. #先安装:pip install wrapt
  3.  
  4. import wrapt
  5. @wrapt.decorator()
  6. def logging(wrapped, insrance, args, kwargs):
  7. print("【方法一:logging】的日志,当前函数为:{}".format(wrapped.__name__))
  8.  
  9. def log_log(level="INFO"):
  10. @wrapt.decorator()
  11. def log_wrapper(wrapped, insrance, args, kwargs):
  12. print("【方法二:logging-{}】的日志,当前函数为:{}".format(level,wrapped.__name__))
  13. return wrapped(*args, **kwargs)
  14. return log_wrapper
  15.  
  16. class Message:
  17. # @logging #这是方法一,两个装饰器,不能同时使用
  18. @log_log(level="DEBUG") #这是方法二
  19. def print_info(self):
  20. print("正在使用print_info的方法")
  21.  
  22. if __name__ == '__main__':
  23. m = Message()
  24. print(m.print_info())

【方法二:logging-DEBUG】的日志,当前函数为:print_info
 正在使用print_info的方法
 None

内置装饰器

静态方法

  1. # 静态方法:类中没有提供任何实例属性,python没有提供静态方法,由装饰器实现
  2. # 类中的静态方法,不需要产生实例化对象可以在没有实例化对象的前提下调用,
  3. # 但是类中的普通方法,必须在实例化对象后才可以调用
  4. # 实际开发中,首选还是普通方法,需要实例化,不需要实例化对象的才使用静态方法。
  5. class Message:
  6. title = "百度一下"
  7. # def get_info(self): #普通方法
  8. @staticmethod # 使用内部装饰器
  9. def get_info(): #类中不带self的,静态方法
  10. Message().hello() # 类中的普通方法,必须在实例化对象后才可以调用
  11. return "www.baidu.com"
  12.  
  13. #普通方法,装饰器无法调用,运行直接报错
  14. def hello(self): #类中的,带self的普通方法
  15. print("【hello方法】这是错误调用!")
  16.  
  17. if __name__ == '__main__':
  18. print("静态装饰方法:",Message.title, Message.get_info())

类方法classticmethod

  1. # 类方法,是为了弥补,init构造方法的缺陷问题
  2. # 假如init构造方法,定义了俩参数,但是临时需要接收一个复核参数,
  3. class Message:
  4. @classmethod
  5. def get_info(info):
  6. info().hello() #本类对象,调用本类方法
  7. def hello(self): #类中的普通方法
  8. print("这是方法:hello")
  9.  
  10. class Me:
  11. def __init__(self, title, url):
  12. self.__title = title
  13. self.__url = url
  14. def __str__(self):
  15. return "{},{}".format(self.__title, self.__url)
  16. @classmethod
  17. def get_instance(cls, info):
  18. res = info.split("-")
  19. return cls(res[0], res[1])
  20.  
  21. if __name__ == '__main__':
  22. print("=======classticmethod静态方法演示:=======")
  23. Message.get_info()
  24. print("===========init构造方法使用后演示:=========")
  25. m = Me("百度", "www.baidu.com")
  26. print(m)
  27. print("类方法演示")
  28. m2 = Me.get_instance("谷歌-www.google.com")
  29. print(m2)

=======classticmethod静态方法演示:=======
这是方法:hello
===========init构造方法使用后演示:=========
百度,www.baidu.com
类方法演示
谷歌,www.google.com

property装饰器

  1. #优化属性访问
  2.  
  3. class Message:
  4. def __init__(self, info):
  5. self.__info = info
  6. def set_info(self, info):
  7. self.__info = info
  8. def get_info(self):
  9. return self.__info
  10. def del_info(self):
  11. del self.__info
  12.  
  13. class Me:
  14. #属性装饰器,简化操作
  15. def __init__(self,info):
  16. self.__info = info
  17. @property
  18. def info(self):
  19. return self.__info
  20. @info.setter #修改属性,下面方法名,必须和上面保持一致
  21. def info(self,info):
  22. self.__info = info
  23. @info.deleter
  24. def info(self):
  25. del self.__info
  26.  
  27. if __name__ == '__main__':
  28. m = Message("百度一下")
  29. print(m.get_info())
  30. m.set_info("还是谷歌去吧")
  31. print(m.get_info())
  32. m.del_info() #删除info属性
  33. print("===========property装饰器演示==========")
  34. me = Me("www.baidu.com")
  35. print(me.info) # 直接访问属性
  36. me.info = "百度一下:www.baidul.com" #直接修改属性
  37. print((me.info))
  38. del me.info #删除属性

百度一下
还是谷歌去吧
===========property装饰器演示==========
www.baidu.com
百度一下:www.baidul.com

Python入门-面向对象-装饰器的更多相关文章

  1. Python入门篇-装饰器

    Python入门篇-装饰器 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.装饰器概述 装饰器(无参) 它是一个函数 函数作为它的形参 返回值也是一个函数 可以使用@functi ...

  2. python入门之装饰器

    入门原理: 一系列函数要做相同的修改,在这些函数执行之前做的操作,或者在执行之后做的操作都可以在一个装饰器(函数)里修改 作用: 在不改变原函数的情况下,对原函数的操作前或者操作后做些改变,这就是装饰 ...

  3. Python入门之装饰器九步学习入门

    第一步:最简单的函数,准备附加额外功能 '''示例1: 最简单的函数,表示调用了两次''' def myfunc(): print("myfunc() called.") myfu ...

  4. python中面向对象&装饰器

    类的定义 基本形式: class ClassName(object): Statement 1.class定义类的关键字 2.ClassName类名,类名的每个单词的首字母大写. 3.object是父 ...

  5. [python基础]关于装饰器

    在面试的时候,被问到装饰器,在用的最多的时候就@classmethod ,@staticmethod,开口胡乱回答想这和C#的static public 关键字是不是一样的,等面试回来一看,哇,原来是 ...

  6. Day04 - Python 迭代器、装饰器、软件开发规范

    1. 列表生成式 实现对列表中每个数值都加一 第一种,使用for循环,取列表中的值,值加一后,添加到一空列表中,并将新列表赋值给原列表 >>> a = [0, 1, 2, 3, 4, ...

  7. Python进阶之装饰器

    函数也是对象 要理解Python装饰器,首先要明白在Python中,函数也是一种对象,因此可以把定义函数时的函数名看作是函数对象的一个引用.既然是引用,因此可以将函数赋值给一个变量,也可以把函数作为一 ...

  8. python进阶04 装饰器、描述器、常用内置装饰器

    python进阶04 装饰器.描述器.常用内置装饰器 一.装饰器 作用:能够给现有的函数增加功能 如何给一个现有的函数增加执行计数的功能 首先用类来添加新功能 def fun(): #首先我们定义一个 ...

  9. 面向切面编程AOP——加锁、cache、logging、trace、同步等这些较通用的操作,如果都写一个类,则每个用到这些功能的类使用多继承非常难看,AOP就是解决这个问题的,python AOP就是装饰器

    面向切面编程(AOP)是一种编程思想,与OOP并不矛盾,只是它们的关注点相同.面向对象的目的在于抽象和管理,而面向切面的目的在于解耦和复用. 举两个大家都接触过的AOP的例子: 1)java中myba ...

随机推荐

  1. freeswitch tts_commandline模块介绍

    概述 freeswitch是开源.免费的VOIP软交换平台,自带了很多功能各异的模块. mod_tts_commandline模块,本身没有TTS能力,而是通过调用TTS引擎的命令生成语音文件,tts ...

  2. python爬虫-使用线程池与使用协程的实例

    背景:爬取豆瓣电影top250的信息 使用线程池 import re from concurrent.futures import ThreadPoolExecutor import requests ...

  3. Golang 基础之基础语法梳理 (一)

    大家好,今天将梳理出的 Go语言基础语法内容,分享给大家. 请多多指教,谢谢. 本次<Go语言基础语法内容>共分为三个章节,本文为第一章节 Golang 基础之基础语法梳理 (一) Gol ...

  4. 网络编程 并发socketserver

    网络编程 并发socketserver ipv4.ipv6 ip协议:规定网络地址的协议 B/S架构 C/S架构 bs是cs的一种 B/S是浏览器和服务端架构 C/S是客户端和服务端架构 osi七层协 ...

  5. linux内存(一) 内核空间与用户空间

    来自如下网站 https://www.cnblogs.com/sparkdev/p/8410350.html 内核空间和用户空间 对 32 位操作系统而言,它的寻址空间(虚拟地址空间,或叫线性地址空间 ...

  6. Mysql等保部分加固

    一.等保要求:操作系统和数据库系统管理用户身份标识应具有不易被冒用的特点,口令应有复杂度要求并定期更换. 实施步骤: 启用口令复杂审核(5.6.6版本以上,才有此模块功能,需要重启mysql). 查看 ...

  7. CVE-2014-3120 (命令执行漏洞)

    环境配置 vulhub环境搭建 https://blog.csdn.net/qq_36374896/article/details/84102101 启动docker环境 cd vulhub-mast ...

  8. Cobalt Strike之LINK木马

    在同一目录下 新建一个exp.ps1 一个test.txt exp.ps1代码 $file = Get-Content "test.txt" $WshShell = New-Obj ...

  9. 记录NLTK安装使用全过程--python

    前言 之前做实验用到了情感分析,就下载了一下,这篇博客记录使用过程. 下载安装到实战详细步骤 NLTK下载安装 先使用pip install nltk 安装包 然后运行下面两行代码会弹出如图得GUI界 ...

  10. 关于web以及浏览器处理预加载有哪些思考?

    图片等静态资源在使用之前就提前请求资源使用到的时候能从缓存中加载, 提升用户体验页面展示的依赖关系维护