python16_day04【编码、函数、装饰器、包】
一、编码总结
"""
python2 文件存储默认是ascii方式,启动加#coding:utf8就是文件以utf8方式打开.否则就是以ascii.变量则是str. 例子: name='中国' print(name.decode('utf-8').encode('gbk')) #name.decode('utf-8') 意思是:name是UTF8格式先解码成Unicode.注意utf-8这里的意思,原字符(name)是utf8. #encode('gbk') 意思是:转码成gbk. #注意:str = bytes这两个在python2是一样的。 python3 文件存储默认是utf8方式,打开文件也是UTF8.变量则是unicode.注意python3中没有decode. 例子: name='中国' print(name.encode('gbk')) str = unicode bytes = python2的bytes(二进制表现形式)
"""
二、装饰器
http://www.cnblogs.com/linhaifeng/articles/6140395.html
装饰器=高阶函数+函数嵌套+闭包
1 """ 2 前言: 3 高阶函数: 4 (1).函数接收的参数是一个函数名 5 6 (2).函数的返回值是一个函数名 7 8 (3).满足上述条件任意一个,都可称之为高阶函数 9 函数嵌套: 10 将函数中定义函数并调用。 11 闭包: 12 在一个作用域里放入定义变量,相当于打了一个包。 13 """
1、闭包
def foo(): def bar(): print("xx") return bar bar1 = foo() bar1()
2、基本装饰器
def auth(func): def wrapper(): print("in the wrapper,begin!") func() print("in the wrapper,stop!") return wrapper @auth def foo(): #注意:就相行于foo=auth(foo) print("in the foo!") foo()
3、带参数
1 def auth(func): 2 def wrapper(*args, **kwargs): #接收万能参数 3 print("in the wrapper,begin!") 4 func(*args, **kwargs) #接收万能参数 5 print("in the wrapper,stop!") 6 return wrapper 7 8 9 @auth 10 def foo(name): 11 print("in the foo! i am [%s]" % name) 12 13 foo('tom')
4、增加返回值
1 def auth(func): 2 def wrapper(*args, **kwargs): 3 print("in the wrapper,begin!") 4 ret = func(*args, **kwargs) #在这里 5 print("in the wrapper,stop!") 6 return ret #在这里 7 return wrapper 8 9 10 @auth 11 def foo(name): 12 print("in the foo! i am [%s]" % name) 13 return True #只在这里增加是不行的,返回None 14 15 ret = foo('tom') 16 print(ret)
"""
重点:
1.*args,**kwargs万能传值.
2.返回值.
"""
5、无参数装饰器和验证
1 user_list = [ 2 {'name': 'alex', 'passwd': '123'}, 3 {'name': 'linhaifeng', 'passwd': '123'}, 4 ] 5 6 current_user = {'username':None,'login':False} 7 8 9 def auth(func): 10 def wrapper(*args, **kwargs): 11 if current_user['username'] and current_user['login']: 12 res = func(*args, **kwargs) 13 return res 14 15 username = input("username>").strip() 16 password = input("password>").strip() 17 18 for number, value in enumerate(user_list): 19 if value['name'] == username and value['passwd'] == password: 20 current_user['username'] = username 21 current_user['login'] = True 22 res = func(*args, **kwargs) 23 return res 24 break 25 else: 26 print("用户或许密码错误!") 27 return wrapper 28 29 30 @auth 31 def index(): 32 print('欢迎来到主页面') 33 34 35 @auth 36 def home(): 37 print('这里是你家') 38 39 40 index() 41 home() 42 43 44 #只输入一次验证
6、有参数装饰器
user_list = [ {'name': 'alex', 'passwd': '123'}, {'name': 'linhaifeng', 'passwd': '123'}, ] current_user = {'username':None,'login':False} def auth(auth_type='file'): def inner(func): def wrapper(*args, **kwargs): if auth_type == 'file': if current_user['username'] and current_user['login']: res = func(*args, **kwargs) return res username = input("username>").strip() password = input("password>").strip() for number, value in enumerate(user_list): if value['name'] == username and value['passwd'] == password: current_user['username'] = username current_user['login'] = True res = func(*args, **kwargs) return res break else: print("用户或许密码错误!") elif auth_type == 'ldap': print("from ldap auth!") res = func(*args, **kwargs) return res return wrapper return inner """ #auth(auth_type='file')就是在运行一个函数,然后返回inner,所以@auth(auth_type='file') #就相当于@inner,只不过现在,我们的inner作为一个闭包的应用, #外层的包auth给它留了一个auth_type='file'参数 """ @auth(auth_type='file') def index(): print('欢迎来到主页面') @auth(auth_type='ldap') def home(): print('这里是你家') index() home()
三、模块与包
1.什么是模块:
一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀。
2.模块的命名空间:
每个模块都是一个独立的名称空间,定义在这个模块中的函数,把这个模块的名称空间当做全局名称空间,这样我们在编写自己的模块时,就不用担心我们定义在自己模块中全局变量会在被导入时,
与使用者的全局变量冲突
3. from spam import * 在spam.py文件中可以使用__all__来控制*(用来发布新版本)
4.重新加域模块
1 import time,importlib 2 import aa 3 4 time.sleep(20) 5 importlib.reload(aa) 6 aa.func1()
5.if __name__ == "__main__":
当test.py这个脚本当成脚本执行时python test.py这时,__name__就会等于__main__,如果被其它脚本import导入时,__name__则会等于"test")
6.模块搜索路径:
(1).先查找内建模块。
(2).再去sys.path中给的路径列表中查找。
1 >>> import sys 2 >>> sys.path.append('/a/b/c/d') 3 >>> sys.path.insert(0,'/x/y/z') #排在前的目录,优先被搜索
7.dir和内建函数
import builtins dir(builtins)
8.包结构
1 glance/ #Top-level package 2 3 ├── __init__.py #Initialize the glance package 4 5 ├── api #Subpackage for api 6 7 │ ├── __init__.py 8 9 │ ├── policy.py 10 11 │ └── versions.py 12 13 ├── cmd #Subpackage for cmd 14 15 │ ├── __init__.py 16 17 │ └── manage.py 18 19 └── db #Subpackage for db 20 21 ├── __init__.py 22 23 └── models.py
1 #文件内容 2 3 #policy.py 4 def get(): 5 print('from policy.py') 6 7 #versions.py 8 def create_resource(conf): 9 print('from version.py: ',conf) 10 11 #manage.py 12 def main(): 13 print('from manage.py') 14 15 #models.py 16 def register_models(engine): 17 print('from models.py: ',engine)
(1).正确使用方法1:
1 #外部调用 2 import sys 3 sys.path.append("day4") 4 5 from glance.api import policy 6 policy.get() 7 8 from glance.api.policy import get 9 get()
(2).正确使用方法2:
#不推荐,默认不可以使用,仅仅是执行了api下面的__init__.py #再得配置__all__=['policy',] 在__init__.py #没有加入到__all__列表的则不能使用 vim glance/api/__init__.py __all__ = ['policy',] from glance.api import * policy.get()
9.绝对导入和相对导入
在glance/api/version.py #绝对导入 from glance.cmd import manage manage.main() #相对导入 from ..cmd import manage manage.main()
10.切记:在"包"的概念中不要使用import , 使用from .. import ..
11.直接import glance解决办法:
1 #glance/__init__.py 2 from . import cmd 3 4 #glance/cmd/__init__.py 5 from . import manage
12.优秀程序常用
1 import os 2 import sys 3 base_dir = os.path.normpath(os.path.join(os.path.abspath(__file__), 4 os.pardir, #上一级 5 os.pardir, #上一级,根据自己的需要来定。 6 )) 7 sys.path.insert(0, base_dir)