python2 存在内存里的 字符串就是bytes,bytes就是字符串, 需要先解码(decode),再编码(encode)
python3 字符串 = unicode, bytes = py2 bytes, 不需要解码,自动转成unicode编码(没有decode方法) 如果需要转成别的格式,可以加上encode 默认文件编码utf-8, 变量的编码unicode
二进制--> bytes --> 字符编码的格式
一、为什么使用函数之模块化程序设计
不使用模块的缺点:
- 体系结构不清晰,可读性差
- 可扩展性差
- 程序冗长
二、定义函数
def func(args):
'''文档描述'''
函数体
return 返回值
1. 无参函数
def foo():
print('in the foo')
foo()
2. 有参函数
def bar(x,y):
print('in the bar')
bar(1,2)
3. 定义空函数
def func():
pass
三、调用函数
1. 语句形式:类似无参函数
2. 表达式的形式
def my_max(x,y):
if x>y:
return x
else:return y
res=my_max(1,2) # 语句形式
res1 = 10*my_max(1,2) # 表达式形式
3. 作为另一个函数的参数
my_max(1,my_max(2,3))
四、返回值
1. 不定义返回值,返回none
2. 返回一个
def foo():
return 1
res=foo()
print(res)
3. 返回多个
def foo():
return 1,'s',[2,3]
res=foo()
print(res)
#返回元祖形式
五、函数的参数
1、形参
def func(x,y):
print(x)
print(y)
2、实参
func(1,2)
3、从实参的角度
def foo(x,y):
print(x,y)
foo(1,2) # 按位置传参
foo(y=10,x='a') # 按照key=value关键字形式
# 针对同一个形参,必须采用按位置或关键字为形参传值
# 按照位置
foo(y=2,1) # 错误
4、从形参的角度:位置参数,默认参数,可变长参数,**kwargs
def foo(x,y,z): # 位置参数:必传值参数
print(x,y,z)
foo(y=2,x=1,z=3)
def foo(x,y=3): # 默认参数,定义的参数放在未定义参数后面
print(x,y)
foo(1) # 打印 1 3
5、可变长参数 *args
# 实参按照位置
def foo(x,y,*args):
print(x)
print(y)
print(args)
#1
foo(1,2,3,4,5,6,7)
#2
l=[3,4,5]
foo(1,2,*l) # 带*的方式
def foo(x,**kwargs):
print(x)
print(kwargs)
foo(1,y=3,z=1) # 不能对同一个形参赋值,如再加一个x=2
dic = {'a':1,'b':2}
foo(1,**dic)
def foo(x,y,z):
print(x,y,z)
foo(**{'x':1,'z':3,'y':2}) # foo(x=1,y=2,z=3) key要对应形参
# 位置参数 --> 默认参数,*args,**kwargs
# *args 等同于 展开按照位置的方式
# **kwargs 等同于 把kwargs展开按照关键字的方式
六、闭包函数
def page(url):
def get():
pass
return get
装饰器
在遵循下面两个原则的前提下为被修饰者添加新功能,必须遵循两个原则:
- 一定不能修改源代码
- 不能修改调用方式
假设为index功能添加一个统计时间的功能
@timer # index=timer(index)
def index():
print('in the index')
index()
# func1=deco1(index) --> func2=doco2(func1) --> func3=doco3(func2)
# 独立一行,从下往上调用
@deco3
@deco2
@deco1
def index():
print('in the index')
index() # 最后调用deco3
用例
import time
def timer(func): # 只能一个参数,并且是被装饰的函数
def wrapper():
start_time = time.time()
func() # 运行原始的index
time.sleep(3)
stop_time = time.time()
print('run time is %s' %(stop_time-start_time))
return wrapper
@timer
def index():
print('in the index')
index()
# 这个用例中,没有改变index函数的代码及调用方式
无参装饰器
import time
import functools
def timer(func):
@functools.wraps(func)
def wrapper(*args,**kwargs): # 'tom',23 --> ('tom'),{'age':23}
'''
wrapper func
:param args:
:param kwargs:
:return:
'''
start_time = time.time()
# func() # 运行原始的index
res=func(*args,**kwargs)
# time.sleep(3)
stop_time = time.time()
print('run time is %s' %(stop_time-start_time))
return res
return wrapper
@timer
def index(msg):
'''
index func
:param msg:
:return:
'''
print('in the index',msg)
index('hello world')
@timer
def home(user,age):
print('%s is %s years old' %(user,age))
return 1
res = home('tom',age=23)
print(res)
print(help(index))
练习登陆官网
def auth(func):
def login():
un = 'tommy'
pw = 'anyway'
while 1:
username = input('username>>: ').strip()
passwd = input('password>>: ').strip()
if username == un and passwd == pw:
print('welcome to oldboy,', username)
res = func()
return res
if username == 'quit':
break
return login
@auth
def wel():
print('官网,'.center(20,'-'))
return 1
welcome = wel()
print(welcome)
模块
import spa
print(spa.money)
spa.mo()
第一次导入模块做了三件事
- 创建新的作用域
- 在该作用域内执行顶级代码
- 得到一个模块名,绑定到该模块内的代码
为模块起别名
import spa as sp
print(sp.money)
一行导入多个
import re,os
from ... import...
from spa import mo
mo(5)
from ... import ... as ...
from spa import mo as m
from ... import *
spa文件中有:
__all__ = ['mo','haha'] # * 调用时只允许调用列表里的模块
另一个脚本调用时:
from spa import * # 下划线开头的无法被*导入
print(mo(10))
print(haha())
print(_change()) # name '_change' is not defined
print(bacc()) # 因为spa里定义了只允许调用的模块,这个会报错
导入模块顺序:
- 内置函数(built-in)
- sys.path
- 附加函数
在sys.path中添加自定义目录
import sys
sys.path.insert(0,'test_dir')
包的导入
import glance.db.models as db_model
db_model.register_models('mysql')
from glance.db.models import register_models
register_models('MySQL')
from glance.api import *
# 先导glace的init文件
# 再导api的init文件
绝对导入
from glance.db import models
相对导入
#在cmd目录程序中导入db目录的模块
from ..db import models
关于__name__
print(__name__)
# 把文件当作脚本执行__name__等于'__main__'
# 把文件spa.py当作模块去使用__name__等于模块名'spa'
if __name__ == '__main__':
print('文件被当作脚本执行时触发的代码')