文章目录
python安装、数据类型、函数及变长参数等基本知识不再赘述,下面从最基础的迭代器开始学习。
(这篇主要是函数与类相关的知识)
1、迭代器
#样例1iter
list1 = [1,2,3]
it = iter(list1)
print(next(it))
print(next(it))
#样例2yield---生成器,迭代器的一种
def frange(start,stop,step):
x = start
while x<stop:
yield x#暂停以记录x的值
x+= step
for i in frange(10,20,0.5):
print(i)
2、lambda表达式
#lambda表达式前面是参数,后面是return内容
def true():
return True##复杂,可使用lambda表达式简化
lambda : True
def add(x,y):
return x+y
lambda x,y: x+y
def func(x):
return x<=1
lambda x:x<=1
3、内建函数filter,map,reduce,zip
a = [1,2,3,4,5]
b = [6,7,8,9,10]
#filter选出a中满足函数要求的数,返回filter对象
print(list(filter(lambda x: x > 2, a)))
#map对比较参数依此处理,返回的是map对象
print(list(map(lambda x: x+1, a)))
print(list(map(lambda x, y: x+y, a, b)))#实现a,b中每个元素依次相加,输出[7, 9, 11, 13, 15]
from functools import reduce
print(reduce(lambda x, y: x*y, [2,3,4], 1))#4*((1*2)*3)=24
for i in zip((1,2,3), (4,5,6)):
print(i)#这里的作用类似于矩阵,输出(1, 4)(2, 5)(3, 6)
dicta = {'a': 'aa', 'b': 'bb'}
dictb = zip(dicta.values(), dicta.keys())#相当于将字典的key和value对调,返回的是zip类型
print(dict(dictb))#转换为dict后输出,{'aa': 'a', 'bb': 'b'}
4、闭包的定义
闭包:外部函数的变量被内部函数引用的方式
例中add—函数的名称或引用;add()函数的调用
#(观察得一个闭包最后返回的是内层函数的*引用or名称*)
def sum(a):
def add(b):
return a+b
return add
**#add---函数的名称或引用;add()函数的调用**
num = sum(2)
print(num(4))#6
#闭包实现递增的操作,传入值就为FIRST,默认是0
def counter(FIRST=0):
cnt = [FIRST]
def add_one():
cnt[0] +=1
return cnt[0]
return add_one
num5 = counter(5)#从5开始
num10 = counter(10)
print(num5())#6
print(num5())#再运行一次又加1,输出7
print(num10())#11
print(num10())#12
5、闭包的使用
使用闭包的好处:调用的参数比普通函数少,代码优雅。
#例题:解决a*x+b=y,
def a_line(a,b):
def arg_y(x):
return a*x+b
return arg_y
line1 = a_line(3,5)
line2 = a_line(5,10)
print(line1(10))#35
print(line2(10))#60
6、装饰器
(与闭包不同的是,闭包外层参数是数,装饰器外层参数是函数)
优点:
- 调用函数时不用重复在代码上边下面编写相应修饰代码,可以放在装饰器里;
- 装饰器的代码复用可以用”@装饰器名称“来进行重复调用,语法更简洁
#1)计时器示例
import time
def timmer(func):
def wapper():
start_time = time.time()
func()
stop_time = time.time()
print("运行时间:%s秒"%(stop_time - start_time))
return wapper
@timmer
def i_can_sleep():
time.sleep(3)
#调用函数
i_can_sleep()#输出:运行时间:3.0513498783111572秒
#2)实现内部函数带参数
def tips(func):
def nei(a,b):
print("start!")
func(a,b)
print("stop!")
return nei
@tips
def add(a, b):
print(a+b)
@tips
def sub(a, b):
print(a-b)
print(add(4, 5))
输出:
start!
9
stop!
None
start!
2
stop!
None
#3)2的基础上装饰器带参数(外层再嵌套new_tips)
def new_tips(argv):
def tips(func):
def nei(a, b):
print("start! %s %s"%(argv, func.__name__))
#func.__name__取运行的函数名称
func(a, b)
print("stop!")
return nei
return tips
@new_tips("add_module")
def add(a, b):
print(a + b)
@new_tips("sub_module")
def sub(a, b):
print(a - b)
print(add(4, 5))
print(sub(7, 5))
输出:
s tart! add_module 函数名称:add
9
stop! None start! sub_module 函数名称:sub
2
stop!
None
7、上下文管理器(附异常捕获)
文件操作是python常用操作,需要捕获异常,常规写法为:
try:
a = open('name.txt')
for line in fd:
print(line)
except Exception as e:
print(e)
finally:
a.close()
简化版,其中with的操作会自动调用finally中的close()的操作,优雅的多。这就是一种上下文管理器
with open("name.txt") as f:
for line in f:
print(line)
8、模块的定义
自己编写的函数希望下次继续使用就可以以模块的形式对其进行保存。
首先两个文件,一个是mymod.py,定义函数等
def print_me():
print("me!")
另一个文件,mod_test.py,调用刚定义的模块
import mymod
mymod.print_me()#输出:me
9、PEP8编码规范
有用的插件:autopep8安装教程:
python代码一键格式化,符合pep8规范
10、类与实例
面向对象编程,几点总结:
- 定义类,类名首字母大写;
- 引用类叫做类的实例化;
- 类中实现的函数功能叫做定义类的方法;变量称为属性;
- 是把相同的内容进行一些归纳,更符合人的思维习惯
- 特殊关键字:self:表示类实例化的本身(类中使用变量时必须要带);__init__是一个特殊方法,对类进行实例化后会自动执行。
class Player():
def __init__(self, name, hp):#此方法中预定义了一些功能
self.name = name#**使用变量时必须要带self**
self.hp = hp
def print_role(self):#定义一个方法
print('%s: %s' % (self.name, self.hp))
user1 = Player('Tom', 100)#类到具体对象的过程叫类的实例化
user2 = Player('Jerry', 90)
user1.print_role()#示例调用方法
user2.print_role()
Tom: 100
Jerry: 90
11、增加类的属性与方法(附类封装特性)
增加一个occu职位属性和updateName()方法。
注意:此时修改名称除了使用updateName()还可以直接赋值,例如赋值’aaa’。如果将第三行的name改为__name,则只能通过调用方法改变,不可随意赋值改变 ------这称为类的封装!
class Player():
def __init__(self, name, hp, occu): # 此方法中预定义了一些功能
self.name = name # 使用变量时必须要带self
self.hp = hp
self.occu = occu
def print_role(self): # 定义一个方法
print('%s: %s %s' % (self.name, self.hp, self.occu))
def updateName(self, newname):#修改名称
self.name = newname
user1 = Player('Tom', 100,'war') # 类到具体对象的过程叫类的实例化
user2 = Player('Jerry', 90,'master')
user1.print_role()
user2.print_role()
user1.updateName('Wilson')#user1改名
user1.print_role()
user1.name='aaa'#还可以直接赋值
user1.print_role()
Tom: 100 war
Jerry: 90 master
wilson: 100 war
aaa: 100 war#此时赋值是可以的
12、类的继承(附多态)
子类可以继承父类中的方法,当方法同名会发生覆盖;即当你使用时才能知道运行的时哪一种方法,说明方法有多种状态,这也是面向对象的一个特性-----多态;
在下面例子中,有以下要点:
- 使用super,子类调用父类的__init__初始化函数,括号是需要的参数
- **type()**方法判断实例所属的类
- isinstance(a2,Monster)方法判断a2是否属于Monster类。在终端调式可以发现python所有的类型都是object类的子类,例如:
class Monster():
def __init__(self, hp=100): # 默认值,初始化100
self.hp = hp
def run(self):
print("Move!")
class Animals(Monster):
def __init__(self, hp=10):
super().__init__(hp)#使用super不需要重复使用self.hp=hp
a1 = Monster(200)
print(a1.hp)
print(a1.run())
a2 = Animals(1)
print(a2.hp)
print(a2.run())
print("a1的类型:%s"%(type(a1)))
print(isinstance(a2,Monster))
200
Move!
None
1
Move!
None
a1的类型:<class ‘main.Monster’>
True
13、类的使用(自定义with语句)
下面的例子实际就是把类的功能和抛出异常结合起来。
exc_tb是__exit__中捕获的异常。
#类使用,自定义with
class Testwith():
def __enter__(self):
print('run!')
def __exit__(self, exc_type, exc_val, exc_tb):
if exc_tb is None:#即没有异常
print('正常结束!')
else:
print('has error:%s'%exc_tb)#输出错误
with Testwith():
print('Test is running')
run!
Test is running
正常结束!
如果有异常是什么样?我们可以在with后面手动抛出异常(使用raise),常见的是NameError:
raise NameError('testNameError')#手动抛出异常