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入门-面向对象-装饰器的更多相关文章

  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. java 实现装饰器设计模式

    package com.gylhaut.base; /** * 装饰器 * 类与类之间的关系 * 1.依赖:形参(局部变量) * 2.关联:属性 * 聚合 属性 整体和部分 不一致的生命周期 人和手 ...

  2. OAuth2和JWT - 如何设计安全的API?

    JWT和OAuth2比较? 要比较JWT和OAuth2?首先要明白一点就是,这两个根本没有可比性,是两个完全不同的东西. JWT是一种认证协议        JWT提供了一种用于发布接入令牌(Acce ...

  3. 保姆级SpringBoot+Vue图片上传到阿里云OSS教程

    小二是新来的实习生,作为技术 leader,我给他安排了一个非常简单的练手任务,把前端 markdown 编辑器里上传的图片保存到服务器端,结果他真的就把图片直接保存到了服务器上,这下可把我气坏了,就 ...

  4. Mybaties——动态sql

    动态 SQL 是 MyBatis 的强大特性之一.如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表 ...

  5. Linux详解 --- 进程管理

    镜像下载.域名解析.时间同步请点击 阿里云开源镜像站 进程管理一览 接下来的几篇博客,我将主要按照这个思维导图的划分去进行讲解. 管理 在理解什么是进程管理之前,我想我们可以先理解一下什么是管理! 问 ...

  6. java字节流和字符流,以及java文件操作

    A.首先说字节流:1.字节流在操作的时候不会用到缓冲区(也就是内存)2.字节流可用于任何类型的对象,包括二进制对象3.字节流处理单元为1个字节,操作字节和字节数组.InputStream是所有字节输入 ...

  7. 深入理解Java虚拟机-JVM运行时数据区域

    一.运行时数据区域 1.程序计数器 程序计数器( Program Counter Register) 是一块较小的内存空间, 它可以看作是当前线程所执行的字节码的行号指示器. Java虚拟机的多线程是 ...

  8. MySQL 获取每月多少日的sql写法

    # 写法1 指定 年月 的共有多少日 select DATEDIFF(DATE_ADD(CONCAT( 2020, '-', '03','-','01'),INTERVAL 1 MONTH),CONC ...

  9. 怎样将 GB2312 编码的字符串转换为 ISO-8859-1 编码的 字符串?

    String s1 = "你好"; String s2 = new String(s1.getBytes("GB2312"), "ISO-8859-1 ...

  10. java中的四种引用类型

    为什么需要引用: Java的内存回收不需要程序员负责,JVM会在必要时启动Java GC完成垃圾回收. Java以便我们控制对象的生存周期,提供给了我们四种引用方式,引用强度从强到弱分别为:强引用.软 ...