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('文件被当作脚本执行时触发的代码')