Python自学day-4
一、字符串转为字典(eval):也可以用于转列表、集合等
s1 = "['name','leo']"
s_list = eval(s1) #字符串转换为列表
print(s_list[1]) s2 = "{'name':'leo','age':32}"
s_dict = eval(s2) #字符串转换为字典
print(s_dict['name']) s3 = "{1,2,3,4}"
s_set = eval(s3) #字符串转换为集合
print(s_set.remove(4))
s4 = "(1,2,3,4)"
s_tuple = eval(s4) #字符串转换为元组
print(s_tuple[1])
二、装饰器(decorator)
- 不能修改被装饰函数的源代码。
- 被装饰函数的调用方式不能改变。
- 函数即“变量”
- 高阶函数
- 嵌套函数
import time
def timer(func1): #装饰器
def warpper(*args,**kwargs):
start_time = time.time()
func1(*args,**kwargs) #调用被装饰的函数
end_time = time.time()
print("使用时间{time}s".format(time = int(end_time- start_time)))
return warpper @timer
def func(str):
for i in range(40):
print("func() "+str)
time.sleep(0.1) func("Hello World")
def test():
pass
x=1 #对数字1存在的内存有一个引用x
y=x #对数字1存在的内存添加了另外一个引用。
del x #删除x引用
del y #删除y引用
当所有的引用都被删除后,1占用的内存会被垃圾回收器(GC)回收。
- 把一个函数名当做实参传给另外一个函数。
- 返回值中包含函数名。
def bar():
print("in bar") def test(func_name):
func_name() test(bar)
装饰器实现-1:使用高阶函数
import time def deco(func):
start_time = time.time()
func()
end_time = time.time()
print("func run time is %s" % (end_time-start_time)) def test1():
time.sleep(2)
deco(test1)
上述代码的test()类似装饰器。但是,虽然没有改变test1()的源代码。但是test1的调用方式被修改了。
import time def timer(func): #将test1传递给func形参。func=test1
def deco():
start_time = time.time() #获取开始时间
func() #此处调用test1()
end_time = time.time() #获取结束时间
print("Func Run Time is %s" % (end_time-start_time))
return deco #将deco函数的地址返回 def test1():
time.sleep(2)
test1 = timer(test1) #将timer()返回的deco地址覆盖到test1 test1() #调用test1,相当于调用deco.
装饰器实现-3:使用语法糖 @
@timer #相当于test1 = timer(test1)
def test1():
time.sleep(2)
import time def timer(func):
def deco(*args,**kwargs): #接收来自test1的参数
start_time = time.time()
res = func(*args,**kwargs) #将deco接收到的参数传递给test1
end_time = time.time()
print("Func Run Time is %s" % (end_time-start_time))
return res #deco返回test1的返回值
return deco @timer
def test1(name,age):
print(name,age)
time.sleep(2)
return "Result" #被装饰函数有返回值 print(test1("Leo",31)) #调用test1相当于调用deco。传递参数,相当于传递给deco。
装饰器实现-5:传递装饰器参数
import time
def timer(time_type): #装饰器的参数传递到最外层
def outer(func): #被装饰函数传递到该层
def deco(*args,**kwargs): #接收来自test1的参数
start_time = time.time()
res = func(*args,**kwargs) #将deco接收到的参数传递给test1
end_time = time.time()
print("Func Run Time is %s" % (end_time-start_time))
return res
return deco
return outer @timer(time_type="t_type") #此时,timer有括号,则执行timer(time_type = "t_type"),返回outer。test1=outer(test1)。
def test1(name,age):
print(name,age)
time.sleep(2)
return "Result"
print(test1("Leo",31)) #调用test1相当于调用deco。传递参数,相当于传递给deco。
注意:当@后面的装饰器带括号,例如timer(time_type='t_type'),这是调用timer函数。timer()返回的是outer函数,实际上装饰器是outer,修饰test1的也是outer。
重点:装饰器非常重要的一点。就是当一个函数被另一个函数装饰时,装饰函数是在定义被装饰函数之后就执行了,无需我们手动调用。相当于装饰器为我们将被装饰函数预先进行了修改。例如,我们的装饰器为某个空字典添加一个值,那么我们无需调用被装饰函数,直接读取字典,值就已经在里面了。
# 该字典为全局变量
URL_DICT = dict() def router(url):
def set_func(func):
# 装饰器为URL_DICT添加一个键值对
URL_DICT[url] = func def call_func():
return func() return call_func return set_func @router("index")
def test1():
return "hello" if __name__ == "__main__":
print(URL_DICT["index"]())
上述代码中,我们并未手动调用test1函数,但是"index":test1已经被放到URL_DICT中去了。这是因为装饰器是在程序被导入时默认执行的,他的效果就是将test1变成了set_func函数,在运行的途中,"index":test1被放置到了字典中。
装饰器的执行时间可以参考 Python何时执行装饰器
三、列表生成式
list_new = [ x*2 for x in range(10) ] #生成[0,2,4,6,8,10,12,14,16,18]
print(list_new)
def func(x):
return x**2
list_new = [ func(x) for x in range(10) ] #range(10)的每一个元素都传递给func()
print(list_new)
四、生成器
import time
def timer(func):
def wrapper(*args,**kwargs):
start_time = time.time()
func(*args,**kwargs)
end_time = time.time()
print("Time : %s" % (end_time-start_time))
return wrapper def func(x):
return x*2
@timer
def list_new_loop():
list_new = [ func(x) for x in range(10000000) ]
print(type(list_new))
for i in list_new:
if i ==100:
break
print(i) @timer
def list_new2_loop():
list_new2 = ( func(x) for x in range(10000000))
print(type(list_new2))
for i in list_new2:
if i ==100:
break
print(i) list_new_loop()
list_new2_loop()
l = ( x*2 for x in range(100))
print(l.__next__()) #同next(l)
#斐波那契
def feibonaq(max_num):
n ,a ,b = 0 ,0 ,1
while n < max_num:
print(b)
a , b = b , a+b
n += 1 feibonaq(20)
#斐波那契
def feibonaq(max_num):
n ,a ,b = 0 ,0 ,1
while n < max_num:
yield b #使用yield b
a , b = b , a+b
n += 1 f = feibonaq(20) #返回一个<generator object feibonaq at 0x02B47360>
print(f.__next__()) #获取一个b的值,也可以用next(f)
print(f.__next__()) #获取下一个b的值
print(f.__next__())
print("Do other things") #可以做其他事情
print(f.__next__()) #再取下一个b的值
yield返回当前状态的值,该函数并停在这里,等执行完其他操作后,再次执行next时,再回来继续执行。
def consumer(name):
print("%s 准备吃包子啦!" % name)
while True:
baozi = yield #使consumer返回一个生成器generator,接受参数并赋值给baozi
print("包子 [%s] 来了,被 [%s] 吃了!" % (baozi,name)) c = consumer("Leo") #返回一个生成器给c
c.__next__() #开始触发生成器(必须)
bz = "韭菜馅包子"
c.send(bz) #传递参数给yield(重要)
import time
def consumer(name):
print("%s 准备吃包子啦!" % name)
while True:
baozi = yield
print("[%s] 被 [%s] 吃了!" % (baozi,name))
def productor(name):
c = consumer("Leo")
c1 = consumer("Kale")
c.__next__()
c1.__next__()
print("[%s] 开始做包子了!" % name)
for i in range(10):
time.sleep(0.5)
baozi_half = "包子的一半"
baozi_other_half = "包子的另一半"
print("老子做了一个包子,分成两半!")
c.send(baozi_half)
c1.send(baozi_other_half)
productor("cooker")
- 为什么在c = consumer()后必须执行一次c.__next__()。以为c = consumer()只是将consumer函数变成一个生成器。第一次调用__next__(),是为了将程序走到baozi = yield这一步,并且打印前面的“准备吃包子啦”。
五、迭代器
from collections import Iterable
print(isinstance([],Iterable)) #判断列表是否可迭代,返回True
迭代器:可以被next()函数调用并不断返回下一个值的对象称为迭代器,Iterator。例如生成器是一种迭代器,但迭代器不一定是生成器。文件句柄也是一个迭代器。
from collections import *
print(isinstance([],Iterator)) #列表不是迭代器,但是是可迭代对象
print(isinstance( (x*2 for x in range(5)) ,Iterator)) #生成器是迭代器,返回Ture
f = open("log.txt","r+",encoding = "utf-8")
print(isinstance(f,Iterator)) #文件句柄是迭代器。
使用DIR看方法:如果方法中有__next__()则就是迭代器。
print(dir(x*2 for x in range(5))) #方法中存在__next__(),所以是迭代器
print(dir([])) #[]不是一个迭代器,返回False
next([]) #报错TypeError: 'list' object is not an iterator
print(dir(dict)) #False
print(dir(tuple)) #False
print(dir(set)) #False
it = iter([1,2,3,4,5]) #创建一个迭代器it
while True:
try:
x = next(it) #使用next获取每一个数据
print(x)
except StopIteration as err:
break
range():在Python3.x中,range()返回一个range对象,该对象是可迭代的,其包含一个迭代器,即ran.__iter__()的返回值。使用该迭代器可以取其中的值。Python2.x中,range()直接返回一个列表,xrange()对应3.x中的range()
ran = range(10)
ran_iter = ran.__iter__()
print(type(ran_iter))
while True:
try:
print(ran_iter.__next__())
except StopIteration:
break
六、内置方法(built-in)
print(all([1,2,3,4,5])) #返回True
print(all([0,1,2,3,4])) #返回False
any():参数为可迭代对象。其中有一个元素为True,则返回True。
print(any([1,2,3,4,5])) #返回True
print(any([0,1,2,3,4])) #返回True
print(any([0,0,0])) #返回False
bin():将整数转换为二进制数。
print(bin(255)) #打印0b11111111
bool():判断真假,0为假,其他数字为真,空列表为假,有元素为真,等等。
a = bytes("abcde",encoding="utf-8")
print(a) #打印b'abcde'
b = bytearray("abcde",encoding="utf-8")
print(b[0]) #打印a的ascii码 97
b[1] = 100 #把b改成d
print(b[1])
print(b) #打印bytearray(b'adcde')
callable():是否可调用,后面可加()的就算可以调用。
def test():
pass
list_test = [1,2,3]
print(callable(test)) #函数是可调用的,类也是可调用的
print(callable(list_test)) #列表是不可调用的
print(chr(10000)) #输出✐
print(ord("ぁ")) #输出12353
compile():我们基本用不到,底层用于把代码编译的过程。即代码转成字节码。
code = "for i in range(10):print(i)" #代码是字符串
exe = compile(code , "err.log" , "exec") #将字符串转换为可执行代码
print(exe) #打印<code object <module> at 0x03029128, file "", line 1>
exec(exe) #执行代码
code = "print('hello')"
eval(code) #eval()也可以执行
这种方式类似实现了import代码然后执行的功能。但是这个函数最牛逼的地方是,可以接受实时传递进去的代码字符串并编译成可执行的代码。那么我们可以让一个函数接受远程传过来的代码,实时执行。
code = "for i in range(10):print(i)"
exec(code)
d = dict()
print(dir(d))
divmod():计算除法,返回商和余数组成的元组。
print(divmod(5,2)) #返回(2,1),2为商,1为余数。
eval():只能处理简单的语句。复杂的用exec()
noname = lambda n:print(n) #将匿名函数赋值给变量
noname(5) #使用函数变量调用
lambda n:for i in range(10):print(i*n) #错误
filter():用于与lambda函数配合,过滤数据。返回一个迭代器
res = filter(lambda n:n>5,range(10)) #过滤出range(10)中大于5个数,组成列表
for i in res:
print(i)
等效于:
def file_test(n): #过滤函数
if n > 5:
return n
res2 = filter(file_test,range(10)) #filter()第一个参数接受一个过滤规则函数,可以是匿名,也可以使普通函数
for i in res2:
print(i)
map():
res = map(lambda n:n*n,range(10)) #第一个参数是一个处理函数,而不是过滤函数
for i in res:
print(i)
相当于:
def map_test(n): #处理函数
return n*n
res2 = map(map_test,range(10))
for i in res2:
print(i)
import functools
res = functools.reduce( lambda x,y:x+y,range(10))
print(res)
def reduce_test(x,y):
return x+y
res = functools.reduce(reduce_test,range(10))
print(res)
阶乘:
import functools
res = functools.reduce( lambda x,y:x*y,range(1,10))
print(res)
frozenset():将集合变为不可变集合。
list_test = frozenset([1,2,3,4,5])
globals():返回当前程序里所有全局变量的k-v键值对,包含函数变量。可以用来判断变量存不存在。
name = "Leo"
if "name" in globals():
print("变量存在")
else:
print("变量不存在")
print(hash("Leo")) #相同的对象转成hash值是相同的,但每次计算的hash值是不同的
print(hash("Leo"))
print(hash("leo"))
print(hash("kale"))
locals():返回函数内部局部变量。
def test():
name = "Leo"
print(name)
if "name" in locals():
print("存在")
test()
print(max([1,2,3,4,5,6])) #返回列表中的最大元素
print(min([1,3,2,5,4])) #返回列表中的最小元素
print(max(1,2,3,4)) #返回参数中最大
print(min({1,2,3})) #返回集合中最小元素
next():相当于迭代器iterator.__next__()。
it = iter([1,2,3,4,5,6])
print(next(it)) #获取下一个元素
print(it.__next__()) #同上
oct():将二进制、十进制、十六进制转换为8进制。
print( oct(1122) ) #十进制转换为8进制,返回0o2142
print( oct(0x12AF) ) #16进制转换为8进制,返回0o11257
print(oct(0b1111)) #二进制转八进制0o17
pow():计算一个数的次方。
print(pow(2,8)) #2的8次方,输出256
repr():用字符串表示对象,即把对象转换为字符串。但是无法再转回对象。
def test():
pass
print(test) #打印函数变量的地址<function test at 0x006954F8>
print(type(repr(test))) #转换为字符串<class 'str'>
round():四舍五入。第二个参数表示保留几位小数。
print(round(1.34356,3))
slice():切片。没什么用。
d = range(10)
print(d[slice(2,5)]) #打印 range(2, 5)
sorted():字典是无序的,可以用sorted排序,返回一个排好序的列表。
dict = {5:2,-5:11,1:42,99:12,12:32,-9:98}
print(sorted(dict)) #仅对key进行排序,输出[-9, -5, 1, 5, 12, 99]
print(sorted(dict.items())) #对所有字典元素按key排序,每个元素转换成元组。输出[(-9, 98), (-5, 11), (1, 42), (5, 2), (12, 32), (99, 12)]
print(sorted(dict.items(), key = lambda x:x[1])) #对所有字段元素按value排序。输出[(5, 2), (-5, 11), (99, 12), (12, 32), (1, 42), (-9, 98)]
zip():拉链,即将两个列表元素一一对应组合起来。
a = [1,2,3,4]
b = ['a','b','c','d']
for i in zip(a,b): #zip(a,b)返回一个迭代器
print(i) #打印结果(1,'a') (2,'b') (3,'c') (4,'d')
a = [1,2,3,4,5,6] #如果两个列表元素数量不一致,则按少的那个合并。
b = ['a','b','c','d']
for i in zip(a,b):
print(i) #打印结果(1,'a') (2,'b') (3,'c') (4,'d')
__import__():只知道一个模块名的字符串,如果import,使用__import__()。用于动态导入。
__import__('my_module')
import本质上是调用__import__()来动态导入模块的
例如:
import os
os = __import__("os")
七、JSON序列化
import json
dict = {"name":"Leo","age":32}
f = open("JSON_test","w")
f.write(json.dumps(dict)) #序列化
f.close()
import json
f = open("JSON_test","r")
dict = json.loads(f.read()) #反序列化
print(dict["age"])
f.close()
JSON只能处理简单的数据类型,字典、列表、字符串等等。
八、pickle序列化
import pickle
def test_func():
print("Hello")
f = open("JSON_test","wb")
f.write(pickle.dumps(test_func)) #看似序列化的函数地址,实际上只是函数名称和参数
f.close()
import pickle
def test_func(): #反序列化这边的程序必须有名字一样,参数一样的函数存在。否则报错
print("Hello1")
print("hello2")
f = open("JSON_test","rb")
func = pickle.loads(f.read())
func() #只要名称和参数与序列化的函数一致,则可以正常运行
f.close()
九、dumps和dump、loads和load的区别
import pickle
def test_func():
print("Hello")
f = open("JSON_test","wb")
pickle.dump(test_func,f) #同f.write(pickle.dumps(test_func))
f.close()
import pickle
def test_func():
print("Hello1")
print("hello2")
f = open("JSON_test","rb")
func = pickle.load(f) #同func = pickle.loads(f.read())
func()
f.close()
注意:同一个数据可以dumps很多次,但都是在一行中连续写入的。loads的时候会报错。所以建议一次dumps对应一次loads。类似虚拟机的快照,每个快照单独存一个文件。
十、软件目录结构规范
Foo/ #项目名
|--bin/ #运行文件目录
| |--foo.py #foo用于运行程序,调用core/下的main.py
|
|--conf/ #配置文件目录
| |--settings.py #配置文件
|
|--logs/ #日志目录
|
|--core/ #主程序目录,名字自定义,可以叫core
| |--tests/ #测试程序目录
| | |--__init__.py
| | |--test_main.py
| |
| |--__init__.py #包里默认有该文件,文件为空,创建一个包,会自动创建该文件
| |--main.py #程序入口
|
|--docs/ #文档目录
| |-conf.py
| |--abc.rst
|
|--setup.py #安装脚本
|--requirements.txt #依赖,例如需要依赖django、mysql
|--README #程序描述
README文件:
- 软件定位,软件的基本功能
- 运行代码的方法:安装环境、启动命令等。
- 简要的使用说明。
- 代码目录结构说明,更详细点可以说明软件的基本原理。
- 常见问题说明
- 方便开发者维护软件的包依赖。将开发过程中新增的包增加进这个列表汇总,避免的setup.py安装依赖时漏掉软件包。
- 方便读者明确项目使用了哪些Python包。
- 这个文件的格式是每一行包含一个包依赖的说明,通常是flask>=0.10这种格式,要求是这个格式能够pip识别,这样就可以简单的同构pip install -r requirements.txt来把所有Python需要的包依赖都安装好。
import os #导入os模块
import sys #导入sys模块
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) #动态获取项目目录的绝对路径
sys.path.append(BASE_DIR) #将项目目录的绝对路径加入到系统变量中
from core import main #即可导入core目录下的main.py
main.login() #执行main模块中的入口函数
其中 os.path.dirname 是获取上一级目录的绝对路径。
Python自学day-4的更多相关文章
- python自学笔记
python自学笔记 python自学笔记 1.输出 2.输入 3.零碎 4.数据结构 4.1 list 类比于java中的数组 4.2 tuple 元祖 5.条件判断和循环 5.1 条件判断 5.2 ...
- Python - 自学django,上线一套资产管理系统
一.概述 终于把公司的资产管理网站写完,并通过测试,然后上线.期间包括看视频学习.自己写前后端代码,用时两个多月.现将一些体会记录下来,希望能帮到想学django做web开发的人.大牛可以不用看了,小 ...
- 拎壶冲冲冲专业砸各种培训机构饭碗篇----python自学(一)
本人一直从事运维工程师,热爱运维,所以从自学的角度站我还是以python运维为主. 一.python自学,当然少不了从hello world开始,话不多说,直接上手练习 1.这个可以学会 print( ...
- [Python自学] day-21 (2) (Cookie、FBV|CBV装饰器)
一.什么是Cookie 1.什么是Cookie? Cookie是保存在客户端浏览器中的文件,其中记录了服务器让浏览器记录的一些键值对(类似字典). 当Cookie中存在数据时,浏览器在访问网站时会读取 ...
- [Python自学] day-21 (1) (请求信息、html模板继承与导入、自定义模板函数、自定义分页)
一.路由映射的参数 1.映射的一般使用 在app/urls.py中,我们定义URL与视图函数之间的映射: from django.contrib import admin from django.ur ...
- [Python自学] day-20 (Django-ORM、Ajax)
一.外键跨表操作(一对多) 在 [Python自学] day-19 (2) (Django-ORM) 中,我们利用外键实现了一对多的表操作. 可以利用以下方式来获取外键指向表的数据: def orm_ ...
- [Python自学] day-19 (2) (Django-ORM)
一.ORM的分类 ORM一般分为两类: 1.DB first:先在DB中创建数据库.表结构,然后自动生成代码中的类.在后续操作中直接在代码中操作相应的类即可. 2.Code first:直接在代码中实 ...
- [Python自学] day-19 (1) (FBV和CBV、路由系统)
一.获取表单提交的数据 在 [Python自学] day-18 (2) (MTV架构.Django框架)中,我们使用过以下方式来获取表单数据: user = request.POST.get('use ...
- [Python自学] day-18 (2) (MTV架构、Django框架、模板语言)
一.实现一个简单的Web服务器 使用Python标准库提供的独立WSGI服务器来实现MVC架构. 首先,实现一个简单的Web服务器: from wsgiref.simple_server import ...
- Python自学之路---Day13
目录 Python自学之路---Day13 常用的三个方法 匹配单个字符 边界匹配 数量匹配 逻辑与分组 编译正则表达式 其他方法 Python自学之路---Day13 常用的三个方法 1.re.ma ...
随机推荐
- SpringMVC+easyUI 分页,查询 (完整的CRUD)
最终完毕CRUD的功能了,注意,这里会对前面有一些修改,UserController的listUser() 已经改写了,如今把所有整理一下吧. JSP: <%@ page language=&q ...
- Gradle Android它自己的编译脚本教程的最新举措(提供demo源代码)
一.前言 Gradle 是以 Groovy 语言为基础,面向Java应用为主.基于DSL(领域特定语言)语法的自己主动化构建工具. 上面这句话我认为写得非常官方,大家仅仅需知道Gradle能够用来an ...
- WPF:WebBrowser提示 为帮助保护你的安全,您的Web浏览器已经限制此文件显示可能访问您的计算机的活动内容
原文:WPF:WebBrowser提示 为帮助保护你的安全,您的Web浏览器已经限制此文件显示可能访问您的计算机的活动内容 版权声明:本文为博主原创文章,未经博主允许可以随意转载 https://bl ...
- 王立平--RemoteView
RemoteView它将在两个地方被使用:一个是在AppWidget,另外一个是在Notification. RemoteView是用来描写叙述一个垮进程显示的view 1.AppWidget---R ...
- debian安装node.js
1,先下载nodejs: # wget http://nodejs.org/dist/v0.8.7/node-v0.8.7.tar.gz 2,解压文件 # tar xvf node-v0.8.7.ta ...
- JDK源码阅读——Vector实现
1 继承结构图 Vector同样继承自AbstractList,与ArrayList.LinedList一样,是List的一种实现 2 数据结构 // 与ArrayList一样,也是使用对象数组保存元 ...
- gnuradio companion 找不到第三方模块gr-osmosdr的问题
我使用了来自Ettus的gnuradio软件包,之后安装了gr-osmosdr 以在gnuradio中调用RTL电视棒. 但是在gnuradio companion找不到来自rtlsdr-source ...
- Windows系统CPU内存网络性能统计第一篇 内存
最近翻出以前做过的Windows系统性能统计程序,这个程序可以统计系统中的CPU使用情况,内存使用情况以及网络流量.现在将其整理一下(共有三篇),希望对大家有所帮助. 目录如下: 1.<Wind ...
- win32Helper
点击别的winform窗口的按钮 #region 点击别的窗口的按钮 [DllImport("user32.dll", EntryPoint = "FindWindowA ...
- 数据在数组中存储的顺序:小端 OR 大端模式 详解
大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放: 小端模式,是指数据的高 ...