前面我们已经学习了Python的基础语法,了解了Python的分支结构,也就是选择结构、循环结构以及函数这些具体的框架,还学习了列表、元组、字典、字符串这些Python中特有的数据结构,还用这些语法完成了一个简单的名片管理系统。下面我就将介绍一下Python的一些进阶语法规则,为后面更复杂的编程打下基础。
闭包与装饰器
什么是闭包、装饰器函数、yield关键字
python高阶函数
lambda匿名函数、reduce函数、map函数、filter过滤器函数
面向对象编程
什么是面向对象、对象的封装、类的继承、类的多态
进程与线程编程
python中的进程与线程、多线程编程
# 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 秒
就是在特定条件下为某些函数再不改动函数体的时候为函数新添加一些功能,这就是装饰器
实现原理:
基于@语法和函数闭包,将原函数封装在闭包中,然后将函数赋值为一个新的函数(内置函数),执行函数时再在内层函数中执行闭包中的原函数
实现效果:
可以在你改变函数内部代码和调用的前提下,实现在函数执行和执行拓展功能
适用场景:
多个函数系统统一在执行前后定义一些功能
关于前言我们了解这么多就够了,然后小编带着大家推导出装饰器
装饰器:
装饰器的写法:
这里我们有一个需求,我们定义了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
# 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
# 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]
# 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
# 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']
['李元芳','李建国']
# 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打印结果:
大大的眼睛
小巧的嘴唇
乌黑亮丽的头发
清秀的脸庞
小小的眼睛
这个美女的样貌是:
鼻子
嘴
头发
脸庞
# 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打印结果:
构造函数运行了
这个美女的样貌是:
高圆圆
大大的眼睛
小巧的鼻子
薄薄的嘴唇
乌黑亮丽的头发
清秀的脸庞
# 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打印结果:
构造函数运行了
这个美女的样貌是:
高圆圆
河北省唐山市
高圆圆
河北省唐山市
大大的眼睛
小巧的鼻子
薄薄的嘴唇
乌黑亮丽的头发
清秀的脸庞
# 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儿子的构造函数运行了
父亲有很多钱
妈妈长的很漂亮
# 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打印结果:
狗狗跑
猫跑
人类跑
狗狗跑
猫跑
人类跑
动物开始跑
# 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
访问量破千,一起加油!
写博客是为了记录和分享自己的学习历程,温故知新!做的不好的地方欢迎指正!!!
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我脑子里浮现出一些关于一种新编程语言的想法,所以我想我会尝试实现它。一位friend建议我尝试使用Treetop(Rubygem)来创建一个解析器。Treetop的文档很少,我以前从未做过这种事情。我的解析器表现得好像有一个无限循环,但没有堆栈跟踪;事实证明很难追踪到。有人可以指出入门级解析/AST指南的方向吗?我真的需要一些列出规则、常见用法等的东西来使用像Treetop这样的工具。我的语法分析器在GitHub上,以防有人希望帮助我改进它。class{initialize=lambda(name){receiver.name=name}greet=lambda{IO.puts("He
所以我在关注Railscast,我注意到在html.erb文件中,ruby代码有一个微弱的背景高亮效果,以区别于其他代码HTML文档。我知道Ryan使用TextMate。我正在使用SublimeText3。我怎样才能达到同样的效果?谢谢! 最佳答案 为SublimeText安装ERB包。假设您安装了SublimeText包管理器*,只需点击cmd+shift+P即可获得命令菜单,然后键入installpackage并选择PackageControl:InstallPackage获取包管理器菜单。在该菜单中,键入ERB并在看到包时选择
在Ruby类中,我重写了三个方法,并且在每个方法中,我基本上做同样的事情:classExampleClassdefconfirmation_required?is_allowed&&superenddefpostpone_email_change?is_allowed&&superenddefreconfirmation_required?is_allowed&&superendend有更简洁的语法吗?如何缩短代码? 最佳答案 如何使用别名?classExampleClassdefconfirmation_required?is_a
可能已经问过了,但我找不到它。这里有2个常见的情况(对我来说,在编程Rails时......)用ruby编写是令人沮丧的:"astring".match(/abc(.+)abc/)[1]在这种情况下,我得到一个错误,因为字符串不匹配,因此在nil上调用[]运算符。我想找到的是比以下内容更好的替代方法:temp="astring".match(/abc(.+)abc/);temp.nil??nil:temp[1]简而言之,如果不匹配,则简单地返回nil而不会出错第二种情况是这样的:var=something.very.long.and.tedious.to.writevar=some
我正在学习Ruby的基础知识(刚刚开始),我遇到了Hash.[]method.它被引入a=["foo",1,"bar",2]=>["foo",1,"bar",2]Hash[*a]=>{"foo"=>1,"bar"=>2}稍加思索,我发现Hash[*a]等同于Hash.[](*a)或Hash.[]*一个。我的问题是为什么会这样。是什么让您将*a放在方括号内,是否有某种规则可以在何时何地使用“it”?编辑:我的措辞似乎造成了一些困惑。我不是在问数组扩展。我明白了。我的问题基本上是:如果[]是方法名称,为什么可以将参数放在括号内?这看起来几乎——但不完全是——就像说如果你有一个方法Foo.d
这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的