Python入门-面向对象-装饰器
1.变量作用域
全局变量和局部变量
#变量是有作用域的,分为全局变量和局部变量
num = 100 #这是全局变量
def change():
"""
查看变量作用域
"""
num = 30 #这是局部变量
print("change函数内部的,局部变量:",num)
change()
print("全局变量:",num)
"""
change内部的变量: 30
全局变量: 100
"""
全局变量和局部变量互相转换
#global:局部变量转换为全局变量
num = 100
def change():
"""
修改全局变量内容
"""
global num
num = 30
print("change内部的变量:",num)
change()
print("全局变量:",num)
"""
change内部的变量: 30
全局变量: 30
""" #nonlocal:全局变量转换为局部变量 【只能使用在闭包中】
#全局作用域
x = 0 def outter():
#函数作用域
x = 1
def inner():
#局部作用域
nonlocal x
x = 2
print("inner:",x)
inner()
print("outter:", x) f = outter()
print("global:",x)
"""
inner: 2
outter: 1 ---- >2
global: 0
""" #总结:当变量重名的前提下,修改内部函数的局部作用域为函数作用域,nonlocal扩大作用域
2.闭包
def p(count):
def out(data):
nonlocal count
count += 1
return "第{}次输出数据:{}".format(count,data)
return out
oa = p(0)
print(oa("tom"))
print(oa("hello"))
print(oa("ok"))
"""
第1次输出数据:tom
第2次输出数据:hello
第3次输出数据:ok
"""
lambda与闭包
#lambda实现闭包
def add(n1):
return lambda n2: n1 + n2
hello = add(100)
print(hello(200))
3.装饰器
# 方法四:定义一个装饰器接收操作函数,是由python传递
def log_logging(func):
def wrapper(*args, **kwargs):
#获取包装函数的名称
print("方法四:这是装饰器的日志方法,当前函数为:{}".format(func.__name__))
return func(*args, **kwargs)
return wrapper # 返回装饰器函数,就是闭包
class Message:
@log_logging #方法四
def print_title(self):
print("方法一:这是print方法直接输出的日志")
logging()
log() #方法二:定义一个日志函数
def logging():
print("方法二:这是使用logging函数,输出的日志!!") #方法三:使用inspet模块方法,获取方法名称
def log():
import inspect
res = inspect.stack()[1][3]
print("方法三:这是使用inspect模块,输出的日志!当前方法为:{}".format(res)) if __name__ == '__main__':
m = Message()
m.print_title()
完整的日志装饰器
def log_logging(level="info"):
def wrapper(func):
def inner(*args, **kwargs):
#获取包装函数的名称
print("【logging-{}】的日志,当前函数为:{}".format(level,func.__name__))
return func(*args, **kwargs)
return inner # 返回装饰器函数,就是闭包
return wrapper
class Message:
@log_logging(level="DEBUG") # 设置参数
def print_title(self):
print("正在使用print——title方法!") if __name__ == '__main__':
m = Message()
m.print_title()
基于类定义实现的装饰器
# 使用call方法 class logging:
def __init__(self, level = "INFO"):
self.__level = level
def __call__(self, func):
def inner(*args, **kwargs):
# 获取包装函数的名称
print("【logging-{}】的日志,当前函数为:{}".format(self.__level, func.__name__))
return func(*args, **kwargs) return inner # 返回装饰器函数,就是闭包
class Message:
@logging(level="DEBUG")
def print_info(self):
print("正在使用print_info的方法。") if __name__ == '__main__':
m = Message()
m.print_info()
"""
【logging-DEBUG】的日志,当前函数为:print_info
正在使用print_info的方法。
"""
wrapt模块
#wrapt减少嵌套层数
#先安装:pip install wrapt import wrapt
@wrapt.decorator()
def logging(wrapped, insrance, args, kwargs):
print("【方法一:logging】的日志,当前函数为:{}".format(wrapped.__name__)) def log_log(level="INFO"):
@wrapt.decorator()
def log_wrapper(wrapped, insrance, args, kwargs):
print("【方法二:logging-{}】的日志,当前函数为:{}".format(level,wrapped.__name__))
return wrapped(*args, **kwargs)
return log_wrapper class Message:
# @logging #这是方法一,两个装饰器,不能同时使用
@log_log(level="DEBUG") #这是方法二
def print_info(self):
print("正在使用print_info的方法") if __name__ == '__main__':
m = Message()
print(m.print_info())
【方法二:logging-DEBUG】的日志,当前函数为:print_info
正在使用print_info的方法
None
内置装饰器
静态方法
# 静态方法:类中没有提供任何实例属性,python没有提供静态方法,由装饰器实现
# 类中的静态方法,不需要产生实例化对象可以在没有实例化对象的前提下调用,
# 但是类中的普通方法,必须在实例化对象后才可以调用
# 实际开发中,首选还是普通方法,需要实例化,不需要实例化对象的才使用静态方法。
class Message:
title = "百度一下"
# def get_info(self): #普通方法
@staticmethod # 使用内部装饰器
def get_info(): #类中不带self的,静态方法
Message().hello() # 类中的普通方法,必须在实例化对象后才可以调用
return "www.baidu.com" #普通方法,装饰器无法调用,运行直接报错
def hello(self): #类中的,带self的普通方法
print("【hello方法】这是错误调用!") if __name__ == '__main__':
print("静态装饰方法:",Message.title, Message.get_info())
类方法classticmethod
# 类方法,是为了弥补,init构造方法的缺陷问题
# 假如init构造方法,定义了俩参数,但是临时需要接收一个复核参数,
class Message:
@classmethod
def get_info(info):
info().hello() #本类对象,调用本类方法
def hello(self): #类中的普通方法
print("这是方法:hello") class Me:
def __init__(self, title, url):
self.__title = title
self.__url = url
def __str__(self):
return "{},{}".format(self.__title, self.__url)
@classmethod
def get_instance(cls, info):
res = info.split("-")
return cls(res[0], res[1]) if __name__ == '__main__':
print("=======classticmethod静态方法演示:=======")
Message.get_info()
print("===========init构造方法使用后演示:=========")
m = Me("百度", "www.baidu.com")
print(m)
print("类方法演示")
m2 = Me.get_instance("谷歌-www.google.com")
print(m2)
=======classticmethod静态方法演示:=======
这是方法:hello
===========init构造方法使用后演示:=========
百度,www.baidu.com
类方法演示
谷歌,www.google.com
property装饰器
#优化属性访问 class Message:
def __init__(self, info):
self.__info = info
def set_info(self, info):
self.__info = info
def get_info(self):
return self.__info
def del_info(self):
del self.__info class Me:
#属性装饰器,简化操作
def __init__(self,info):
self.__info = info
@property
def info(self):
return self.__info
@info.setter #修改属性,下面方法名,必须和上面保持一致
def info(self,info):
self.__info = info
@info.deleter
def info(self):
del self.__info if __name__ == '__main__':
m = Message("百度一下")
print(m.get_info())
m.set_info("还是谷歌去吧")
print(m.get_info())
m.del_info() #删除info属性
print("===========property装饰器演示==========")
me = Me("www.baidu.com")
print(me.info) # 直接访问属性
me.info = "百度一下:www.baidul.com" #直接修改属性
print((me.info))
del me.info #删除属性
百度一下
还是谷歌去吧
===========property装饰器演示==========
www.baidu.com
百度一下:www.baidul.com
Python入门-面向对象-装饰器的更多相关文章
- Python入门篇-装饰器
Python入门篇-装饰器 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.装饰器概述 装饰器(无参) 它是一个函数 函数作为它的形参 返回值也是一个函数 可以使用@functi ...
- python入门之装饰器
入门原理: 一系列函数要做相同的修改,在这些函数执行之前做的操作,或者在执行之后做的操作都可以在一个装饰器(函数)里修改 作用: 在不改变原函数的情况下,对原函数的操作前或者操作后做些改变,这就是装饰 ...
- Python入门之装饰器九步学习入门
第一步:最简单的函数,准备附加额外功能 '''示例1: 最简单的函数,表示调用了两次''' def myfunc(): print("myfunc() called.") myfu ...
- python中面向对象&装饰器
类的定义 基本形式: class ClassName(object): Statement 1.class定义类的关键字 2.ClassName类名,类名的每个单词的首字母大写. 3.object是父 ...
- [python基础]关于装饰器
在面试的时候,被问到装饰器,在用的最多的时候就@classmethod ,@staticmethod,开口胡乱回答想这和C#的static public 关键字是不是一样的,等面试回来一看,哇,原来是 ...
- Day04 - Python 迭代器、装饰器、软件开发规范
1. 列表生成式 实现对列表中每个数值都加一 第一种,使用for循环,取列表中的值,值加一后,添加到一空列表中,并将新列表赋值给原列表 >>> a = [0, 1, 2, 3, 4, ...
- Python进阶之装饰器
函数也是对象 要理解Python装饰器,首先要明白在Python中,函数也是一种对象,因此可以把定义函数时的函数名看作是函数对象的一个引用.既然是引用,因此可以将函数赋值给一个变量,也可以把函数作为一 ...
- python进阶04 装饰器、描述器、常用内置装饰器
python进阶04 装饰器.描述器.常用内置装饰器 一.装饰器 作用:能够给现有的函数增加功能 如何给一个现有的函数增加执行计数的功能 首先用类来添加新功能 def fun(): #首先我们定义一个 ...
- 面向切面编程AOP——加锁、cache、logging、trace、同步等这些较通用的操作,如果都写一个类,则每个用到这些功能的类使用多继承非常难看,AOP就是解决这个问题的,python AOP就是装饰器
面向切面编程(AOP)是一种编程思想,与OOP并不矛盾,只是它们的关注点相同.面向对象的目的在于抽象和管理,而面向切面的目的在于解耦和复用. 举两个大家都接触过的AOP的例子: 1)java中myba ...
随机推荐
- hive从入门到放弃(二)——DDL数据定义
前一篇文章,介绍了什么是 hive,以及 hive 的架构.数据类型,没看的可以点击阅读:hive从入门到放弃(一)--初识hive 今天讲一下 hive 的 DDL 数据定义 创建数据库 CREAT ...
- pd.merge操作的on参数解释
# 同时传入两个Key,此时会进行以['key1','key2']列表的形式进行对应,left的keys列表是:[['K0', 'K0'],['K0', 'K1'],['K1', 'K0'],['K2 ...
- 安全学习笔记-web安全之XSS攻击
web安全之XSS攻击 XSS 即跨站脚本攻击,是 OWASP TOP10 之一.它的全称为 Cross-site scripting,因为 CSS 这个简称已经被占用表示为前端三剑客之一的CSS,所 ...
- 使用scrapy 创建爬虫项目
使用scrapy 创建爬虫项目 步骤一: scrapy startproject tutorial 步骤二: you can start your first spider with: cd tuto ...
- python基础之序列类型的方法——字符串方法
python基础之序列类型的方法--字符串方法 Hello大家好,我是python学习者小杨同学,经过一段时间的沉淀(其实是偷懒不想更新),我终于想起了自己的博客账号,所以这次带来的是序列方法的后半部 ...
- jsp安全问题及其解决建议
jsp编程语言自从推出之日起,由于它的快速.平台无关.可扩展.面向对象等特性得到了越来越广泛的应用,越来越多的厂家开发出了各种各样的支持平台如IBM 公司的WebSphere.BEA公司的WebLog ...
- Docker——dockerfile
dockerFile介绍 dockerFile是用来构建docker镜像的文件!命令参数脚本! 步骤: 编写dockerFile文件 docker build构建成为一个镜像 docker run运行 ...
- 一种优雅的Golang的库插件注册加载机制
一种优雅的Golang的库插件注册加载机制 你好,我是轩脉刃. 最近看到一个内部项目的插件加载机制,非常赞.当然这里说的插件并不是指的golang原生的可以在buildmode中加载指定so文件的那种 ...
- 什么是BASH?
BASH是Bourne Again SHell的缩写.它由Steve Bourne编写,作为原始Bourne Shell(由/ bin / sh表示)的替代品.它结合了原始版本的Bourne Shel ...
- Struts2的功能扩展点有哪些?
l Interceptor及其相关子类 l TypeConverter及其相关子类 l Validator及其相关子类 l Result及其相关子类 l ObjectFactory及其相关子类