前言

前面我们已经学习了Python的基础语法,了解了Python的分支结构,也就是选择结构、循环结构以及函数这些具体的框架,还学习了列表、元组、字典、字符串这些Python中特有的数据结构,还用这些语法完成了一个简单的名片管理系统。下面我就将介绍一下Python的一些进阶语法规则,为后面更复杂的编程打下基础。

  1. 闭包与装饰器

    什么是闭包、装饰器函数、yield关键字

  2. python高阶函数

    lambda匿名函数、reduce函数、map函数、filter过滤器函数

  3. 面向对象编程

    什么是面向对象、对象的封装、类的继承、类的多态

  4. 进程与线程编程

    python中的进程与线程、多线程编程

第一章. 闭包与装饰器

1. 什么是闭包

# coding=utf-8
# 闭包
# def func1():
# print ("函数1运行")
# return func2()
# #函数1的返回值是函数2的引用
# def func2():
# print ("函数2运行")
# return 2
# r =func1()
# print (r)
# r2= r() # r = func2
# print (r2) def func1():
print ("函数1运行")
def func2():
print ("函数2运行")
func2()
return func2()
f2 = func1()
print(f2)
f2() """
在一个函数,比如func1中的内部定义了另外一个函数function2
并且函数1(func1)的返回值是函数2(func2)的引用
这种情况,我们称之为闭包 简单来说就是外部函数返回内部函数的引用就叫做闭包
"""

print打印结果:

函数1运行
函数2运行
函数2运行
None

案例:龟兔赛跑

# coding=utf-8
import time
import random # 定义跑道长度
track_length = 10
def runtime(func):
def wrapper():
start_time = time.time()
func()
end_time = time.time()
print (func.__name__,"运行时间是",end_time-start_time,"秒")
return wrapper @runtime
def tortoise():
# for i in [1,2,3,4,5,6,7,8,9,10]:
for i in range(1,track_length+1):
print ("乌龟跑的{}米".format(i))
time.sleep(1)
@runtime
def rabbit():
for i in range(1,track_length + 1):
if i % 5 == 0:
time.sleep(random.randint(1,10))
print ("兔子跑了{}米".format(i))
tortoise()
rabbit()

print打印结果:

乌龟跑的1米
乌龟跑的2米
乌龟跑的3米
乌龟跑的4米
乌龟跑的5米
乌龟跑的6米
乌龟跑的7米
乌龟跑的8米
乌龟跑的9米
乌龟跑的10米
tortoise 运动时间是 10.04876708984375 秒
兔子跑了1米
兔子跑了2米
兔子跑了3米
兔子跑了4米
兔子跑了5米
兔子跑了6米
兔子跑了7米
兔子跑了8米
兔子跑了9米
兔子跑了10米
rabbit 运动时间是 9.022485494613647 秒

2. 什么是装饰器呢?

就是在特定条件下为某些函数再不改动函数体的时候为函数新添加一些功能,这就是装饰器

实现原理:

基于@语法和函数闭包,将原函数封装在闭包中,然后将函数赋值为一个新的函数(内置函数),执行函数时再在内层函数中执行闭包中的原函数

实现效果:

可以在你改变函数内部代码和调用的前提下,实现在函数执行和执行拓展功能

适用场景:

多个函数系统统一在执行前后定义一些功能

关于前言我们了解这么多就够了,然后小编带着大家推导出装饰器

装饰器:

装饰器的写法:

这里我们有一个需求,我们定义了5个函数,想在5个函数执行前和执行后都打印一句话:装饰器的学习。首先我们来写于一下没有装饰器的写法,话不多说直接上代码:

def a():
pass def b():
pass def c():
pass def d():
pass def e():
pass

先定义5个函数,再加上我们要打印的话:

def a():
print("装饰器的学习")
print("装饰器的学习") def b():
print("装饰器的学习")
print("装饰器的学习") def c():
print("装饰器的学习")
print("装饰器的学习") def d():
print("装饰器的学习")
print("装饰器的学习") def e():
print("装饰器的学习")
pass
print("装饰器的学习") a()
b()
c()
d()
e()

运行一下:

发现运行成功,但我们想如果我要修改打印的话就要都修改一次,特别麻烦,而且,这是5个函数如果是500个,我们还要一个一个的去加吗?这就有我们的装饰器了,首先我用装饰器修改下,再给大家解释。

def outer(origin):
def inner():
print("装饰器的学习")
res = origin()
print("装饰器的学习")
return res return inner @outer
def a():
pass @outer
def b():
pass @outer
def c():
pass @outer
def d():
pass @outer
def e():
pass a()
b()
c()
d()
e()

运行一下:

发现这样我们也成功了,接下来小编来个大家解释

首先:

我们要明白@的作用,那我们的函数a来举例子@的作用就是帮我们执行一次a=outer(a),首先python将把我们的a变成参数传给outer函数,运行后再赋值给a,这就是@的作用。

其次给大家解释一下自定的outer函数

我自己称这个函数为@下函数的补丁函数,也就是装饰器函数还是拿a函数举例子,首先a函数变成参数传给了我们的outer函数,outer里又嵌套了一个inner函数 ,然后将函数a赋值给res,然后用return语句返回出结果,外层函数返回inner函数,也就是将inner函数运行一次,这就是工作流程。

最后分别在各函数前加上装饰,最后运行出结果



这就是装饰器的写法。

装饰器的参数

这时我遇到一个问题如果函数内有参数而且每个函数的参数数量不同,我们应该怎末办,先看下面代码

def outer(origin):
def inner():
print("装饰器的学习")
res = origin()
print("装饰器的学习")
return res return inner @outer
def a(g, e):
pass @outer
def b(w):
pass @outer
def c(u, y, t):
pass @outer
def d(c):
pass @outer
def e():
pass a()
b()
c()
d()
e()

这时我们运行一下

发现报错,是因为我们的装饰器内没有这两个参数,那可以在装饰器内设置两个参数,但问题是,有的函数内有3个参数,而有的函数内没有参数,那我们应该怎么办?

针对这个问题我们可以给装饰器设置动态参数,先看代码:

def outer(origin):
def inner(*args, **kwargs):
print("装饰器的学习")
res = origin(*args, **kwargs)
print("装饰器的学习")
return res return inner @outer
def a(a1):
print("我是一函数") @outer
def b(a1, a2):
print("我是二函数") @outer
def c(a5, a6, a7):
print("我是三函数") a(1)
b(2, 3)
c(4, 5, 6)

因为函数太多了,小编有点麻烦就剪了几个函数,但道理是相同的,这时我们再运行一下

这样我们就成功了,以上就是装饰器的写法,接下来给大家拓展一下

装饰器的拓展:(functools模块)

首先给大家引入一下这时教给大家几个魔法方法



接下来我们实战一下

def outer(origin):
def inner(*args, **kwargs):
# 我是一个装饰器函数
print("装饰器的学习")
res = origin(*args, **kwargs)
print("装饰器的学习")
return res return inner @outer
def c(a5, a6, a7):
# 我是个函数
print("我是三函数") c(4, 5, 6)
print(c.__name__)
print(c.__doc__)

运行一下:

这时我们发现我要的是c函数,但给我反馈的是inner函数,这是为什么呢?

这就是工作原理,直接就把c函数装饰成了inner函数,那以后再工作中一定会要自己函数的名字,而不要我装饰后的函数,这样就可以让我们的函数装饰的更像,其实在以后中,都想装饰的更像,那我们应该怎末办?

这时就需要我们的第三方模块functools,直接上代码

import functools

def outer(origin):
@functools.wraps(origin)
def inner(*args, **kwargs):
# 我是一个装饰器函数
print("装饰器的学习")
res = origin(*args, **kwargs)
print("装饰器的学习")
return res return inner @outer
def c(a5, a6, a7):
# 我是个函数
print("我是三函数") c(4, 5, 6)
print(c.__name__)
print(c.__doc__)

这时再运行一下

这时我们发现,我们伪装成功了,这样就会让我们的装饰更像。

装饰器模板:

接下来送给大家装饰器的模板,以后需要随时ctrl+c和ctrl+v

import functools

def outer(origin):
@functools.wraps(origin)
def inner(*args, **kwargs):
# 这里书写需要装饰的功能
res = origin(*args, **kwargs)
return res return inner

第二章. Python高阶函数

1. lambda表达式(匿名函数)

# coding=utf-8
# lambda表达式(匿名函数)
# 计算圆形的面积
# pi * r * r
# 导入数学模块
import math
def circle_area(r):
result = math.pi * r * r
return result
r = circle_area(3)
print (r)
"""
lambda是一个关键字
冒号前边的r是这个函数的参数
冒号后边的是这个函数的运算逻辑
"""
result = lambda r:math.pi * r * r
r = result(3)
print (r) def calc_function(o):
if o == "+":
return lambda a,b : a + b
elif o == "-":
return lambda a,b : a - b
elif o == "*":
return lambda a,b : a * b
elif o == "/":
return lambda a,b : a / b
f = calc_function("*")
print (f)
r = f(3,4)
print (r)

print打印结果:

28.2743338823
28.2743338823
<function <lambda> at 0x03159B70>
12

2. map自动拆分的计算函数

# coding=utf-8
# map函数
my_list = [1,2,3,4,5]
# 1
result = []
for i in my_list:
result.append(i + 1)
print (result) # 2
def add_one(e):
return e + 1
r = map(add_one,my_list)
print (list(r))
def add_two(e):
if e == 1:
return e + 3
elif e == 2:
return 2 - 1
else:
return e
r =map(add_two,my_list)
print (list(r))
# 3
print (list(map(lambda e:e+1,my_list)))

print打印结果:

[2, 3, 4, 5, 6]
[2, 3, 4, 5, 6]
[4, 1, 3, 4, 5]
[2, 3, 4, 5, 6]

3. reduce自动堆叠计算函数

# coding=utf-8
# reduce
# 导入reduce
from functools import reduce
a =[2,4,6,8,10]
def add(x,y):
return x + y
result = reduce(add,a)
print (result) print (reduce(lambda x,y : x+y,a))

print打印结果:

30
30

4. filter过滤器函数

# coding=utf-8

# filter函数
letter=['a',"B",'c',"D",'e',"F"]
upper_letter = filter(lambda x: x == x.upper(),letter)
print (upper_letter)
print (list(upper_letter)) student_name = ['李元芳','李建国','莫怀羽']
print (list(filter(lambda x:x.startwith("李"),
student_name)))

print打印结果:

['B', 'D', 'F']
['B', 'D', 'F']
['李元芳','李建国']

第三章. 面向对象编程

1. 对象的封装

# coding=utf-8
# 对象的封装
# 类的概念
"""
类的名字:当名字由多个单词构成时,我们采用驼峰命名法
就是说多个单词,每个单词的首字母需要大写
这也是python的命名规则
"""
class BeautifulGirl():
# 类的属性
eye = ""
nose = ""
mouth = ""
hair = ""
face = "" # 构造函数
def __init__(self,eye,nose,mouth,hair,face):
self.eye = eye
self.nose = nose
self.mouth = mouth
self.hair = hair
self.face = face
print ("构造函数运行了")
# 在这就叫做类的方法
def dance(self):
print ("美女在跳舞") def get_beautiful_girl(self):
print ("这个美女的样貌是:")
print (self.nose)
print (self.mouth)
print (self.hair)
print (self.face)
print (self.eye) # 实例化就是获取具体对象的一个过程 new新的一个。
girl = BeautifulGirl("大大的眼睛"
,"小巧的嘴唇"
,"乌黑亮丽的头发"
,"清秀的脸庞")
girl.dance()
girl.get_beautiful_girl() girl2 = BeautifulGirl("小小的眼睛",'鼻子','嘴','头发','脸庞')
girl2.get_beautiful_girl()

print打印结果:

大大的眼睛
小巧的嘴唇
乌黑亮丽的头发
清秀的脸庞
小小的眼睛
这个美女的样貌是:
鼻子

头发
脸庞

2. 类的私有属性

# coding=utf-8
# 类的私有属性
class BeautifulGirl():
# 类的属性
eye = ""
nose = ""
mouth = ""
hair = ""
face = ""
# 这就是私有属性,私有属性在类的外部是不可以访问的
__name ="高圆圆"
address = "河北省唐山市"
# 构造函数
def __init__(self,eye,nose,mouth,hair,face):
self.eye = eye
self.nose = nose
self.mouth = mouth
self.hair = hair
self.face = face
print ("构造函数运行了")
# 在这就叫做类的方法
def dance(self):
print ("美女在跳舞")
def __dd(self):
print ("美女在跳舞") def get_beautiful_girl(self):
print ("这个美女的样貌是:") print (self.__name)
print (self.nose)
print (self.mouth)
print (self.hair)
print (self.face)
print (self.eye)
girl = BeautifulGirl("大大的眼睛"
,"小巧的嘴唇"
,"乌黑亮丽的头发"
,"清秀的脸庞")
print (girl.mouth)
print (girl.address)
# print (girl.__name)
# # 类的私有属性可以访问吗?
# print (BeautifulGirl.__dict__)
# print (girl._beautiful__name)
girl.get_beautiful_girl()

print打印结果:

构造函数运行了
这个美女的样貌是:
高圆圆
大大的眼睛
小巧的鼻子
薄薄的嘴唇
乌黑亮丽的头发
清秀的脸庞

3. 类中的方法

# coding=utf-8
# 类的私有属性
class BeautifulGirl():
# 类的属性
eye = ""
nose = ""
mouth = ""
hair = ""
face = ""
# 这就是私有属性,私有属性在类的外部是不可以访问的
__name ="高圆圆"
address = "河北省唐山市"
# 构造函数,也叫构造方法
def __init__(self,eye,nose,mouth,hair,face):
self.eye = eye
self.nose = nose
self.mouth = mouth
self.hair = hair
self.face = face
print ("构造函数运行了")
# 在这就叫做类的方法
def dance(self):
print ("美女在跳舞")
# 这个叫做私有方法
def __dd(self):
print ("美女在跳舞")
# 这个叫做一般方法
def get_beautiful_girl(self):
print ("这个美女的样貌是:") print (self.__name)
print (self.nose)
print (self.mouth)
print (self.hair)
print (self.face)
print (self.eye)
# 静态方法
# 静态方法不能够访问类中的属性
@staticmethod
def study():
print ("美女在实习") # 类方法
# 类方法是不可以访问实例变量的,它可以访问类变量(类的属性
@classmethod
def girl_friend(cls):
print (cls.__name)
print (cls.address)
print (cls.face)
girl = BeautifulGirl("大大的眼睛"
,"小巧的嘴唇"
,"乌黑亮丽的头发"
,"清秀的脸庞") # print (BeautifulGirl.__dict__)
# 这就访问了类中的私有方法
# girl.beautifulGirl__dd() girl.study()
BeautifulGirl.study() # 类名,一般方法的名称调用是会报错的
# BeautifulGirl.dance(girl) girl.girl_friend()
BeautifulGirl.girl_friend()
girl.get_beautiful_girl()

print打印结果:

构造函数运行了
这个美女的样貌是:
高圆圆
河北省唐山市
高圆圆
河北省唐山市
大大的眼睛
小巧的鼻子
薄薄的嘴唇
乌黑亮丽的头发
清秀的脸庞

4. 类的继承

# coding=utf-8
# 类的继承
# 父类和子类
class Father(object):
age = 38 def __init__(self,name):
self.name = name
print ("父类的构造函数运行了") def father_money(self):
print ("父亲有很多钱") def __father_knowleger(self):
print ("父亲的知识体系") @staticmethod
def study():
print ("父亲在学习") @classmethod
def father_friend(cls):
print ("父亲有很多朋友") def face(self):
print ("父亲非常帅")
# 意味着son这个类继承了father这个类
class Son(Father):
def __init__(self):
print ("子类的构造函数运行了")
# son = Son("小王")
son = Son()
# 在继承中,子类如果有构造函数,name就不会调用弗雷德构造函数 # 在继承中,一般的方法是可以被继承的
son.father_money() # 私有方法可以被继承
# son.__father_knowleger()
son.study()
son.father_friend() class Mother():
def face(self):
print ("妈妈长的很漂亮") # 这就叫做多继承
class Son2(Mother,Father):
def __init__(self):
print("2儿子的构造函数运行了") son2 = Son2()
son2.father_money()
son2.face()
# 当多继承的时候,多个父类拥有一个名称的变量或方法时
# 哪个父类写在继承列表的前边,子类就继承谁的

print打印结果:

子类的构造函数运行了
父亲有很多钱
父亲在学习
父亲有很多朋友
2儿子的构造函数运行了
父亲有很多钱
妈妈长的很漂亮

5. 类的多态

# coding=utf-8
# 类的多态
# 指的是多种形态 class Animal():
def run(self):
print ("动物开始跑")
# 子类在继承父类的过程中,重写了父类中的方法
class Dog(Animal):
def run(self):
print ("狗狗跑") class Cat(Animal):
def run(self):
print ("猫跑") class Person(Animal):
def run(self):
print ("人类跑") dog = Dog()
dog.run() cat = Cat()
cat.run() person = Person()
person.run() # 多个类继承同一个类,都重写了父类的方法,呈现出了不同的形态 # 多态性
class A(Animal):
pass
a = A() def run(obj):
obj.run() run(dog)
run(cat)
run(person)
run(a)

print打印结果:

狗狗跑
猫跑
人类跑
狗狗跑
猫跑
人类跑
动物开始跑

6. 多进程编程

# coding=utf-8
# 多进程编程代码演示
import time
from multiprocessing import Process
import os def target_function():
print ("子进程的ID:{}".format(os.getpid()))
time.sleep(2)
if __name__== "__main__":
print (__name__)
print ("主进程ID:{}".format(os.getpid()))
ps = []
for i in range(10):
p = Process(target_function())
p.start()
ps.append(p)
# 让主进程等待子进程进行运行完成后在停止
for p in ps:
p.join()

print打印结果:

__main__
主进程ID:2692
子进程的ID:2692
子进程的ID:2692
子进程的ID:2692
子进程的ID:2692
子进程的ID:2692
子进程的ID:2692
子进程的ID:2692
子进程的ID:2692
子进程的ID:2692
子进程的ID:2692

最后

访问量破千,一起加油!

写博客是为了记录和分享自己的学习历程,温故知新!做的不好的地方欢迎指正!!!

python语法进阶这一篇就够了的更多相关文章

  1. python面试看这一篇就够了

    python-面试通关宝典 有面Python开发方向的,看这一个repo就够啦? 语言特性 1.谈谈对 Python 和其他语言的区别 Python属于解释型语言,当程序运行时,是一行一行的解释,并运 ...

  2. Python语法进阶(2)- 正则表达式

    1.初识正则表达式 1.1.什么是正则表达式 正则表达式是一个特殊的字符序列,便于检查一个字符串是否与某种模式匹配:应用于字符串,在字符串中通过复杂的过滤筛选等操作得到我们想要的数据: 正则表达式的特 ...

  3. Python爬虫入门这一篇就够了

    何谓爬虫 所谓爬虫,就是按照一定的规则,自动的从网络中抓取信息的程序或者脚本.万维网就像一个巨大的蜘蛛网,我们的爬虫就是上面的一个蜘蛛,不断的去抓取我们需要的信息. 爬虫三要素 抓取 分析 存储 基础 ...

  4. Python语法进阶

    1.变量进阶 2.局部变量.全局变量  3.函数进阶 4.函数进阶

  5. Python语法进阶(1)- 进程与线程编程

    1.进程与多进程 1.1.什么是进程 进程就是程序执行的载体 什么叫多任务? 多任务就是操作系统可以同时运行多个任务.比如你一边在用浏览器学习,还一边在听音乐,,这就是多任务,至少同时有3个任务正在运 ...

  6. Python开发【第七篇】:面向对象 和 python面向对象进阶篇(下)

    Python开发[第七篇]:面向对象   详见:<Python之路[第五篇]:面向对象及相关> python 面向对象(进阶篇)   上一篇<Python 面向对象(初级篇)> ...

  7. Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) JAVA日志的前世今生 .NET MVC采用SignalR更新在线用户数 C#多线程编程系列(五)- 使用任务并行库 C#多线程编程系列(三)- 线程同步 C#多线程编程系列(二)- 线程基础 C#多线程编程系列(一)- 简介

    Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) 一.前言 由于本篇文章较长,所以下面给出内容目录方便跳转阅读,当然也可以用博客页面最右侧的文章目录导航栏进行跳转查阅. 一.前言 ...

  8. 如果只有1小时学Python,看这篇就够了

    大家好,我是大鹏,城市数据团联合发起人,致力于Python数据分析.数据可视化的应用与教学. 和很多同学接触过程中,我发现自学Python数据分析的一个难点是资料繁多,过于复杂.大部分网上的资料总是从 ...

  9. Python 3 入门,看这篇就够了

    文章目录 简介 基础语法 运算符 变量 数据类型 流程控制 迭代器 生成器 函数 自定义函数 参数传递 可更改与不可更改对象 参数 匿名函数 变量作用域 模块 面向对象 错误和异常 文件操作 序列化 ...

  10. Python 3 入门,看这篇就够了(超全整理)

    史上最全Python资料汇总(长期更新).隔壁小孩都馋哭了 --- 点击领取 今天和大家分享的内容是Python入门干货,文章很长. 简介 Python 是一种高层次的结合了解释性.编译性.互动性和面 ...

随机推荐

  1. uniapp/微信小程序 项目day03

    一.商品列表 1.1 获取数据 首先能够进入商品列表的途径 传的数据有 了解了这个之后就可以开始了,先创建分支 创建编译模式,并分配初试数据 这个时候就可以获取数据了 需要的数据 所以在发起请求之前需 ...

  2. Java中String被称为不可变字符串的原因

    很多东西,看似可变,实际上不过是是新桃换旧符罢了. 代码: /** * String之所以被称为不可变字符串 */ static void testString(){ String str = &qu ...

  3. MessagePack 和System.Text.Json 序列号 反序列化对比

    本博客将测试MessagePack 和System.Text.Json 序列号 反序列化性能 项目文件: Program.cs代码: using BenchmarkDotNet.Running; us ...

  4. Python基础之网络编程:2、OSI协议之七层协议

    目录 Python基础之网络编程 一.网络编程前戏 二.OSI七层协议 简介: 1.物理连接层 2.数据链路层 网络相关专业名词 3.网络层 4.传输层 Python基础之网络编程 一.网络编程前戏 ...

  5. Windows Server 2019 安装 Oracle 19C RAC(VMWare虚拟机环境)

    软件 Windows Server 2019 Standard Oracle 19C Oracle Grid 19 VMware Workstation 16 规划 共享存储,使用Windows Se ...

  6. C++初阶(封装+多态--整理的自认为很详细)

    继承 概念:继承机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类.继承呈现了面向对象程序设计的层次结构,体现了由简单 ...

  7. 万字 HashMap 详解,基础(优雅)永不过时

    本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 提问. 前言 大家好,我是小彭. 在上一篇文章里,我们聊到了散列表的整体设计思想,在后续几篇文章里,我们将以 Jav ...

  8. Day27:异常详解

    异常 1.1 异常概述 异常(Exception)指程序运行中出现的不正常情况:文件找不到.网络异常.非法参数等等. 我们通过代码来了解一下: public class Demo{ public st ...

  9. 【Java SE进阶】Day05 异常,线程

    一.异常 1.概念 程序执行过程中,出现非正常情况导致JVM的非正常停止 本身是一个类,产生异常即创建并抛出一个异常对象 Java处理异常的方式是进行中断处理 异常非语法错误,语法错误直接不会产生cl ...

  10. USB限流,短路保护芯片IC

    USB口的输出电压一般是5V,在一些电源中,由于总电源5V是一个很大的总电源,再分别出很多路输出负载出来,例如5V10A,分成4个USB输出口,如果没加其他限流和保护的话,任意一个USB口的输出电流都 ...