admin管理员组

文章数量:1646980

目录

      • 建议不要光看,要多动手敲代码。眼过千遭,不如手读一遍。
      • python注释
      • python运算符
      • 比较:type()和 isinstance()
      • 基本数据类型
        • Number(数字)
          • 数学函数
          • 随机数函数
        • 字符串
          • 格式化输出
          • 字符串内建函数
        • 列表 list
          • 其他内置函数
        • 元组
        • 字典
          • 其他内置函数
        • 集合 set
          • 其他
      • 条件控制
      • 循环
      • 函数
        • 不定长参数
        • 匿名函数
        • 变量作用域
        • 迭代器
        • 生成器 generator
        • 闭包
          • 闭包定义
          • 使用闭包的注意事项
          • 闭包的作用
        • 装饰器
          • 带有参数的装饰器
          • 类做装饰器
          • wraps函数
            • 装饰器使用场景
      • 模块
        • os模块
        • hashlib模块
        • 常用标准库
          • functools模块
        • 常用扩展库
        • 包和__init__
      • 输入输出
        • 输入
        • 输出
      • 文件
        • pickle模块
      • 面向对象
        • 魔法方法
          • `__new__`方法
          • `__init__`方法
          • `__str__`方法
          • `__del__`方法
          • 其他方法
        • 引用计数
        • 继承
        • 重写
        • 类属性
        • 实例属性
      • 有关类方法、实例方法、静态方法的笔记参考了`蔷薇Nina `这位朋友的笔记
        • 类方法
        • 实例方法
        • 实例方法中self的含义
        • 静态方法
        • 动态添加属性以及方法
        • 解耦合
        • 私有化
        • property的使用
        • `__slots__`的作用
        • 元类
        • `__metaclass__`属性
        • 内建属性
        • `__getattribute__`的坑
        • `__getattr__`方法
        • `__setattr__`方法
        • 描述符
          • 描述符定义
          • 描述符种类及优先级
            • 类属性>数据描述符
            • 数据描述符>实例属性
            • 实例属性>非数据描述符
            • 描述符使用注意点
            • 描述符使用
      • 错误和异常
        • 捕获多个异常
        • 异常的嵌套
        • 自定义异常
        • 异常处理中抛出异常
        • 调试
          • print
          • 断言(assert)
          • logging
          • pdb调试
        • pdb交互调试
        • pdb程序里埋点
      • 垃圾回收
        • 代码块
        • 代码块的缓存机制
        • 小数据池
        • 指定驻留
        • 引用计数
          • GC模块
      • 内置方法
      • pep8规则
      • 进程
        • 进程定义
        • 创建进程
          • linux专供版
        • getpid、getppid
          • multiprocessing
            • Process
            • Process 子类
        • 进程池Pool
          • multiprocessing.Pool常用函数
        • 进程间的通信Queue
          • Queue使用
          • 进程池中的Queue
      • shutil模块
      • 线程
        • 多线程
          • 线程模块
          • 查看线程数目
          • threading 注意点
          • 多线程共享全局变量
          • 列表当实参传递到线程中
          • 进程VS线程
          • 线程同步
            • 互斥锁
            • 死锁
          • 生产者消费者模式
          • ThreadLocal
          • 使用ThreadLocal
          • 异步
          • GIL(全局解释锁)
          • 分布式进程
        • 异步IO
          • asyncio、async/await、aiohttp
      • 网络编程
        • TCP/IP协议(族)
        • 端口
        • IP地址
        • 子网掩码
        • socket
          • udp 发送数据:
          • udp绑定
          • udp广播
        • TCP
          • tcp四次挥手
          • TCP的2MSL问题
          • TCP长连接和短连接
          • 常见网络攻击案例
          • TCP服务器
          • TCP客户端
        • 网络编程 应用
          • 单全双工信息收发
          • TFTP客户端
          • 单进程 TCP服务器
          • 多进程服务器
          • 多线程服务器
          • 单进程服务器,非阻塞模式
          • select版 TCP服务器
          • epoll版-TCP服务器
        • 网络分析工具
          • wireshark
          • Packet Tracer

笔记中代码均可运行在Jupyter NoteBook下(实际上Jupyter-lab使用体验也很棒)。

建议不要光看,要多动手敲代码。眼过千遭,不如手读一遍。

相关笔记的jupiter运行代码已经上传,请在资源中自行下载。

#在download源代码的时候要适当选择较低的版本,因为语言的源码版本越低越能看出作者的意图

python注释

python的编码格式注释:#-*- coding: utf-8 -*-

linux书写环境变量注释:#!/usr/bin/env python3

'''python中的帮助函数:help(func_name)'''
# 例子
help(input)
# 例子结束
Help on method raw_input in module ipykernel.kernelbase:

raw_input(prompt='') method of ipykernel.ipkernel.IPythonKernel instance
    Forward raw_input to frontends
    
    Raises
    ------
    StdinNotImplentedError if active frontend doesn't support stdin.

python运算符

#算数运算符
'''python中 / 表示浮点除法  //  向下取整除法'''
# 例子
print(3/4)
print("*"*8)# python符号也可进行算数运算
print(3//4)
# 例子结束

python中的比较运算符:>,<,>=,<=,==,!=,<>(不等于的这种表示方式会逐渐淘汰)

python逻辑运算符 and,or,not

'''
python赋值运算符:=, +=, -=,*=,/=,**= (算术运算符和=相结合的操作)

python 位运算符:&[按位与,同为1,否则为假],| [按位或,二者中一个即可]
^ [按位异或,相异为1],~[按位取反,1变0,0变1],
<<[左移,乘2],>>[右移,除以2]

进制转换 :转二进制:bin(),八进制:oct(),16进制:hex(),转10进制:int()

'''
#例子
a=3
print(a<<1)
b=4
print(b>>1)
# 例子结束

# python 成员运算符:in,not in
# python身份运算符:is, is not
'''is和 == 的区别:is用于判断两个变量引用是否为同一个(即id是否相同),==用于判断变量值是否相等'''
# 例子
x=y=[1, 2, 3]
z=[1, 2, 3]
print(x is y, id(x),id(y), x==y)
print(x is z, id(x), id(z), x==z)

6
2
True 140646103441800 140646103441800 True
False 140646103441800 140646103444296 True
'''
对于python中a,b = b,a的换值方法的解析
a, b = b, a操作是将a,b的地址互换
关键在于ROT_TWO的地址互换
'''
#! /usr/bin/env python3
# -*- coding:utf-8 -*-
from dis import dis

def demo(a, b):
    print(a,b)
    a, b = b, a
    print('new: ', a,b)


a, b = 2, 3

demo(a,b)

dis(demo)

2 3
new:  3 2
 10           0 LOAD_GLOBAL              0 (print)
              2 LOAD_FAST                0 (a)
              4 LOAD_FAST                1 (b)
              6 CALL_FUNCTION            2
              8 POP_TOP

 11          10 LOAD_FAST                1 (b)
             12 LOAD_FAST                0 (a)
             14 ROT_TWO
             16 STORE_FAST               0 (a)
             18 STORE_FAST               1 (b)

 12          20 LOAD_GLOBAL              0 (print)
             22 LOAD_CONST               1 ('new: ')
             24 LOAD_FAST                0 (a)
             26 LOAD_FAST                1 (b)
             28 CALL_FUNCTION            3
             30 POP_TOP
             32 LOAD_CONST               0 (None)
             34 RETURN_VALUE

比较:type()和 isinstance()

'''type()和isinstance()区别
type()不认为子类是父类的一种类型,而isinstance()认为是
isinstance()也用来判断是不是可迭代对象'''
#l例子
class A:
    pass
class B(A):
    pass
print("isinstance(, A(),A) is ", isinstance(A(),A))
print("type(A())==A is ",type(A())==A)
print("isinstance(B(),A) is ", isinstance(B(),A))
print("type(B())==A is ",type(B())==A)
isinstance(, A(),A) is  True
type(A())==A is  True
isinstance(B(),A) is  True
type(B())==A is  False

基本数据类型

# 变量可使用del语句删除
# 例子
vara=1
print(vara)
del vara
print(vara) # 删除后打印会报错
1



---------------------------------------------------------------------------

NameError                                 Traceback (most recent call last)

<ipython-input-2-1f49fa2b38a1> in <module>()
      4 print(vara)
      5 del vara
----> 6 print(vara) # 删除后打印会报错


NameError: name 'vara' is not defined
'''
六个标准数据类型:
Number(数字),String(字符串),List(列表),Tuple(元组),Set(集合),Dictionary(字典)

不可变数据:Number,String,Tuple

可变数据:list,dict,set
'''
Number(数字)

int、float、bool、complex(复数)

#例子
complex(1,3)
(1+3j)
数学函数
'''ads(x)[绝对值],ceil(x)[向上取整],

cmp(x,y)[比较xy,x>y=1,x<y=-1,x==y=0,<python3已弃用,使用(x>y)-(x<y)>]

exp(x)[e的x次方],fabs(x)[浮点绝对值],floor(x)[向下取整],

pow(x,y)[x的y次],round(x,y)[对x四舍五入,y表示精确度]
'''
# abs()与fabs()比较
from math import fabs
print(abs(-5))
print(fabs(-5))
# round(x,y)例子
print(round(5.6482133, 5))

5
5.0
5.64821
随机数函数
'''
choice(seq)[从序列seq中随机挑一个](在模块random中)
randrange([start,]stop[,step])
random()[随机在(0-1中生成)]
seed([x])[改变随机数生成器种子]
shuffle(lst)[随机排序一个序列]
uniform(x,y)[在(x-y中随机生成一个浮点数)]
'''
# choice()例子
import random
print("choice()例子:", random.choice(range(10)))

# randrange()使用例子
print("randrange()例子:", random.randrange(1,90,1)) # 随机数范围为1-90,步长为1
# seed()不常使用

# shuffle()例子
var_shuffle_ =[1, 2, 3, 4, 5]
random.shuffle(var_shuffle_)
print(var_shuffle_)

# uniform()例子
print("uniform例子:", random.uniform(1, 45))
choice()例子: 0
randrange()例子: 79
[3, 4, 5, 2, 1]
uniform例子: 4.053759455798719
from math import pi
print(pi)
3.141592653589793
字符串
'''
原始字符串:r/R
'''
#例子
a = r'test\n'
print('test\n')
print(a)

test

test\n
格式化输出
# 格式化输出可以用% 和"str".format()
# "str".format()中在字符串"str"中用{[var]}表示变量,[var]为可选的变量名
# 这里注意:{}中无变量名,切未指示位置的时候,无变量名的参数应在有变量名的参数的位置前面
# 在{}中表示数字时用':'(冒号),表示数字格式化
# format()还可以在"str"的{}中通过指定位置来输出
# 在format中对大括号的转义用{},例子{
   {}}
'''
%c[字符,或ascii码]
'''
print("这是 %s" %('用%格式化输出例子'))

# format()格式化输出例子
print("这是{name}{}".format('有无变量名混用的例子', name='format'))
print("这是{0}而不用{1}的例子,{1}{0}".format("通过位置输出", "变量名输出"))
from math import pi
print("这是数字格式化例子:输出保留两位小数的pi{:.2f}, 不设置保留位数的pi={ppi}".format(pi,ppi=pi))
print("format对{
   {}}的转义例子输出".format())
这是 用%格式化输出例子
这是format有无变量名混用的例子
这是通过位置输出而不用变量名输出的例子,变量名输出通过位置输出
这是数字格式化例子:输出保留两位小数的pi3.14, 不设置保留位数的pi=3.141592653589793
format对{}的转义例子输出
字符串内建函数
'''
capitalize()[首字母大写],

center(width,fillchar)[在宽度为width的输出空间中居中显示fillchar字符串],

count(str,beg=0,end=len(string))[统计str在string中出现的次数,
若beg或end指定,则返回指定范围的次数],

bytes.decode(encoding="utf-8",errors="strict")[指定解码,
用的是bytes对象的方法]

encode(encoding="utf-8",errors='strict')[指定编码方式]

查找:find,index,rfind,rindex(相同都返回下标,不同,-1,异常)

replace(原,现):替换

split(切割符) :切割

capitalize:单个首字母大写

title:全部首字母大写

endswith(str):判断结尾

startswith(str):判断开头

rjust(int),ljust(int),center(int):在int个字符中右左中对齐

strip():去掉str两边空格,\n

partition(str):以左起第一个str分割为元组

split(str):以str分割

isalpha():是否纯字母

isalnum():是否数字字母组合

isdigit():是否纯数字

str.join(a,b):以str连接a,b

'''

列表 list
'''
列表切片:list[start:end [:step(默认为1)]]
'''
# 列表生成器
[x for x in range(0,10,2)]
[0, 2, 4, 6, 8]
''' list.
append():追加(整体添加)

insert(位置,内容):添加

extend(list):追加list(合并list)
'''
#例子
A=[12,34,55]
B=['aa','bb']

print('this is A:',A,'\nthis is B:',B)
A.append(666)
print('this is A.append(666)',A)
B.insert(1,'this is 1')
print('this is B.insert:',B)
A.extend(B)
print('A.extend(B)',A)
this is A: [12, 34, 55] 
this is B: ['aa', 'bb']
this is A.append(666) [12, 34, 55, 666]
this is B.insert: ['aa', 'this is 1', 'bb']
A.extend(B) [12, 34, 55, 666, 'aa', 'this is 1', 'bb']
''' list.
pop():默认最后一个

remove(str):删除str内容

clear():清空列表

del list[position]:删除列表中的某个元素
'''
#例子
A=[11,22,33,44]
print(A)
print('*'*8)
print("list.pop()操作")
#A.pop()会返回弹出值
print(A.pop())
print(A)
print('*'*8)
print("del list[position]操作")
del A[1]
print(A)
print('*'*8)
print("list.remove()操作")
A.remove(11)
print(A)
print('*'*8)
print("list.clear()操作")
A.clear()
print(A)
[11, 22, 33, 44]
********
list.pop()操作
44
[11, 22, 33]
********
del list[position]操作
[11, 33]
********
list.remove()操作
[33]
********
list.clear()操作
[]
'''
直接用下标进行修改
'''
#例子
A=[11,22,33]
print(A)
print('*'*8)
A[0]="changed"
print(A)
[11, 22, 33]
********
['changed', 22, 33]
'''
in:布尔值

list.index:下标,异常
'''
#例子
A=[11,22,33]
print(11 in A)
print(A.index(1234))
True



---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-17-f32251f40118> in <module>()
      7 A=[11,22,33]
      8 print(11 in A)
----> 9 print(A.index(1234))


ValueError: 1234 is not in list
其他内置函数
''' list.
count(obj) 统计obj出现次数

reverse() 反向排列

sort([key=None,reverse=False]) 排序,key表示排序依据,
reverse表示反向,默认False


copy() 复制列表
'''

'''
len(list):list长度
max(list):list中的最大值
min(list):list中的最小值
list(seq):将元组转换为list
'''
A = [1, 2, 3, 4]
B = (22, 33)
print("对A的操作:len(A): {lena}\tmax(A):{maxa}\tmin(A):{mina}\n".format(lena=len(A), maxa=max(A), mina=min(A)))
print("对B的操作:list(B):{listb}".format(listb=list(B)))
对A的操作:len(A): 4	max(A):4	min(A):1

对B的操作:list(B):[22, 33]
元组
'''
不可更改的列表,死的
扩展通过新建一个组合元组
tuple(list):将list转换为tuple
'''
字典
'''
dict['key']='value'
'''
'''
del dict["key"] 删除键名为"key"的键值对
pop(key,[default]) 删除字典给定键的键值对,返回被删除的值,key必须给出
popitem() 随机删除并返回一对键值对(一般删除的是末尾的键值对)
'''
'''
键值对赋值
dict.update(dict2) 把字典dict2中的键值对更新到dict中
'''
dict_a = {
   'name':'value'}
dict_b = {
   'name':'18'}
print(dict_a)
dict_a.update(dict_b)
print(dict_a)
{'name': 'value'}
{'name': '18'}
'''
dict.get(key)
in

'''
其他内置函数
'''
len(dict):键值对个数

dict.keys():dict的所有键

dict.values():dict的所有值

dict.
clear() 清空字典
copy() 浅复制
fromkeys() 创建新字典
ietms() 以列表返回可遍历的键值对



'''
#例子
D={
   'a':'111','b':222}
print(D)
print(D.items())
D.clear()
print(D)
{'a': '111', 'b': 222}
dict_items([('a', '111'), ('b', 222)])
{}
集合 set
'''
集合中没有重复值,(集合会自动去重)

list、tuple可以有重复值,不会自动去重

字典中,当键重复时,会保留最后的那个,其他的去重(不论值是否相同)

强制类型转换得到的变量恢复到原类型用eval()
'''
'''set.
add() 添加元素


'''
'''set.
pop() 随机移除
remove() 移除指定元素,当元素不存在会报错
discard() 删除指定元素, 当元素不存在不会报错
clear() 清空

'''
其他
'''set.
copy() 拷贝
difference() 返回多个集合的差集
difference_update() 移除集合中的元素,该元素在指定的集合也存在。
intersection() 返回交集
isdisjoint() 布尔判断集合间是否包含相同元素
issubset() 子集判断
union() 并集
'''

条件控制

'''
if exp:
    pass
elif exp1:
    pass
else:
    pass
    
if的各种真假判断

"",None,[],{},数字0,都表示假
'''

循环

'''
while exp:
    pass

while exp:
    pass
else:
    pass

for var in seq: # 这里seq必须是可迭代数据
    pass
    
break
continue
'''
'''
for循环中删除元素的坑:在循环的过程中删除元素可能出现漏删的情况。
'''
# for循环例子
a = [1,2,3,4,5,6,7]

for i in a:
    print(i, end=',')
    if i == 2 or i == 3:
        a.remove(i)
print("\na = {0}".format(a))

#这时输出分别为1,2,4,5,6,7,和a = [1,3,4,5,6,7]
#从这里的结果可以看出在循环中漏删了3
1,2,4,5,6,7,
a = [1, 3, 4, 5, 6, 7]
'''
这里可以使用“缓存”的方法

用另一个变量临时存储要删除的变量,待循环结束后在删除
'''
# for循环解决例子
a = [1,2,3,4,5,6,7]

b = []

for i in a:
    print(i, end = ",")
    if i == 2 or i == 3:
        b.append(i)

for i in b:
    a.remove(i)
print("\na = {0}".format(a))

#此时得到的a的结果就是完全删除的结果 a = [1,4,5,6,7] 
1,2,3,4,5,6,7,
a = [1, 4, 5, 6, 7]

函数

在一个Python文件中,定义重名的函数不会报错,但是会使用最后的一个函数

def funcName(*args,**kwargs):
    pass
不定长参数
'''
*args:长度不限,来着不拒,输出的是元组形式
**kwargs:长度不限,输入必须是key=value的形式,否则无法传入;
输出为字典形式
注意:不定长参数应放在参数列表最后,否则会吞参数

'''
#*args,**kwargs例子
def funcDemo(a,*args,**kwargs):
    print(a)
    print(args)
    print(kwargs)
funcDemo(111,1,2,3,4,name='name',age='age')
111
(1, 2, 3, 4)
{'name': 'name', 'age': 'age'}
'''
对不定长参数传入的拆包
元组传入加*:*tuple
字典传入加**:**dict
如果不拆包直接传入,会被*args吞并,不会区分传值
'''
#拆包例子
A=(1,2,3,4)
B={
   'name':'name','age':'age'}

def func(*args,**kwargs):
    print(args)
    print(kwargs)

func(A,B)
print("*"*8)
func(*A,**B)
((1, 2, 3, 4), {'name': 'name', 'age': 'age'})
{}
********
(1, 2, 3, 4)
{'name': 'name', 'age': 'age'}
匿名函数
'''
lambda [arg1,[arg2,arg3...]]:expression

'''
# lambda简单例子
f = lambda x,y:x+y
print(f(2,3))
5
变量作用域
'''
L(Local) 局部作用域

E(Enclosing) 闭包函数外的函数中

G(Global) 全局作用域

B(Built-in) 内建作用域

变量查找顺序:LEGB

'''
# global和nonlocal
'''
局部内改全局,变量前加global
内部修改外部函数变量,变量前加nonlocal
'''
#nonlocal 例子
def outer():
    num=10
    print('this is raw num:',num)
    
    def inner():
        nonlocal num # 声明外部变量
        num='change'
        print('this is changed num:',num)
    inner()
    print('this is num:',num)

outer()    
this is raw num: 10
this is changed num: change
this is num: change
迭代器
'''
迭代器是一个可以记住遍历的位置的对象。

迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。
迭代器只能往前不会后退。

迭代器有两个基本的方法:iter() 和 next()。

可迭代对象:list,tuple,dict,set,str,生成器(generator,带yield的generator function)
# 这里也可说是Iterable

判断是否是可迭代对象:isinstance:
1
from collections.abc import Iterable
isinstance(flag, Iterable)
2
或者是使用for循环来判断

iter()函数用来将Iterable转换为Iterator
'''

# isinstance 迭代对象判断 例子

# 导入Iterable
from collections.abc import Iterable 
# 判断是否可迭代
isinstance('flag', Iterable) # 会输出True

# 例子释义:isinstance是判断变量1(代码中的''flag)是否为变量2(Iterable)类的实例或是其子类的实例

# isinstance 例子
class A(object):
    def __str__(self):
        return 'this is class A'

    
class B(A):
    def __str__(self):
        str = 'this is class B, and is son class of A'
        return str
    
b = B()

a = isinstance(b,B) # 判断b是否为B的实例
c = isinstance(b,A) # 判断b是否为A的实例
print(a,c) # 输出显示b是B的实例,b是A的子类的实例
print("*"*8)

# Iterable 和Iterator判断
from collections.abc import Iterator

a = isinstance('str', Iterator) # False
c = isinstance(iter('str'), Iterator) # True
print(a,c)
True True
********
False True
生成器 generator

对于要创建的数据(尤其是Iterable数据及其范类),不是一下全部创建,而是在程序运行中逐步生成。可以极大的节约内存。

'''
可以用next()获取生成器的下一个返回值
但是这里next()执行完最后一次还调用会报错

加了yield参数的函数就是一个生成器
对生成器函数不可用普通函数的调用方法,生成器函数返回的是一个对象。
此时需要用一个变量来指向这个生成器。

此时用next(x)来执行生成器时,

会在yield处停止,并返回yield后的参数,

这个返回的参数就是生成器生成的值,
在下一次调用生成器时,会在yield停止的地方接着执行。

next(x)和x.__next__()作用相同


一个生成器中可以有多个yield

协程多任务:运行一下,停一下
这里就可以用生成器的来实现多任务
'''

# yield function 例子 : next()输出fib数列


def fib():
    a,b = 0,1
    for i in range(10):
        yield b
        a,b = b,a+b
a = fib()
flag = 1
print('1-10的fib数列:')
while flag ==1:
    try:
        fib = next(a) # 这里next(generator)和a.__next__()是一样的
        print(fib, end='\t')
    except Exception as result:
        print('\n1-10的最大fib数:', fib)
        flag = 0
1-10的fib数列:
1	1	2	3	5	8	13	21	34	55	
1-10的最大fib数: 55
# yield function 不用next(),使用循环输出生成器生成的值
# 一个生成任意数的斐波那契数列的函数
def fibs(num):
    i = 0
    a, b = 0, 1
    while i<num:
        yield b # 生成器核心
        a,b = b, a+b
        i +=1

# 这里以输出11的fib数列举例
for f in fibs(11):
        print(f, end = '\t')
1	1	2	3	5	8	13	21	34	55	89	
'''
x.send(value) # value必须有,可以是None,但是不可不写
'''

# x.send(value) 例子

def fib():
    a,b = 0,1
    for i in range(10):
        temp = yield b
        a,b = b,a+b
        print(temp)
a = fib()
next(a)
# 这里print()的结果是None,因为生成器在yield处停止,
# 不会对temp赋值
k = a.send("yeyeye")
# 这里print()的结果是yeyeye,因为send()将这个值传入了temp
print('生成器返回的值',k)
print('1111111111')
yeyeye
生成器返回的值 1
1111111111
闭包

参考网址1(闭包):

https://blog.csdn/marty_fu/article/details/7679297

参考网址2(python编译与执行):

对于上一个参考网址中对for循环中的闭包问题解析的不同解释

https://blog.csdn/helloxiaozhe/article/details/78104975

闭包定义
'''
在一个函数内部定义一个函数,

并且内部的函数调用了外部函数的参数,

此时,内部函数和用到的参数就叫做闭包。

闭包 = 函数块+定义函数时的环境
'''

# 闭包定义例子
# 定义一个外部函数
def outer(out_num):
    #在函数内部再定义一个函数,
#     并且这个函数用到了外边函数的变量,
# 那么将这个函数以及用到的一些变量称之为闭包
    def inner(in_num):
        sum = out_num + in_num
        return sum
    #这里返回的是闭包的结果
    return inner

# 对outer函数中的out_num赋值为3
mid = outer(3)

print('mid的类型是:',type(mid))
print('mid的名字是:',mid.__name__)
print('此时的mid为:', mid)

# 这个6是对inner(in_num)中的in_num赋值
result = mid(6)

print('对内外均赋值后mid的类型是:',type(result))
print('对内外均赋值后的mid为:', result)
mid的类型是: <class 'function'>
mid的名字是: inner
此时的mid为: <function outer.<locals>.inner at 0x7ff6d804ce18>
对内外均赋值后mid的类型是: <class 'int'>
对内外均赋值后的mid为: 9
使用闭包的注意事项
'''
闭包内对外部函数的局部变量进行修改:
1、要么在闭包内添加 nonlocal 声明此变量为外部局部变量
(nonlocal 声明只有python3中有,在python2中只能用法2)

2、要么外部变量为列表,字典,集合这种可扩展变量,
在闭包内部才可进行修改
方法2实际上还是由legb次序返回到外部函数环境中,所以两个方法殊途同归
'''
# 例子

def out():
    a = 1
    def inner():
#         nonlocal a
        a = a+1
        return a
    return inner

t = out()
t() # 这里报错
# 报错原因:python规则指定所有在赋值语句左面的变量都是局部变量
# 则在闭包inner()中,变量a在赋值符号"="的左面,被当做inner()的局部变量,但是未在inner找到a的定义

-------------------------------------------------------------------------

UnboundLocalError                       Traceback (most recent call last)

<ipython-input-1-44e22659e2f6> in <module>
     19 
     20 t = out()
---> 21 t() # 这里报错
     22 # 报错原因:python规则指定所有在赋值语句左面的变量都是局部变量
     23 # 则在闭包inner()中,变量a在赋值符号"="的左面,被当做inner()的局部变量,但是未在inner找到a的定义


<ipython-input-1-44e22659e2f6> in inner()
     14     def inner():
     15 #         nonlocal a
---> 16         a = a+1
     17         return a
     18     return inner


UnboundLocalError: local variable 'a' referenced before assignment
# 解决方法1
def out():
    a = 1
    def inner():
        nonlocal a 
        a = a+1
        return a
    return inner

t = out()
print('解决方法1:',t())

# 解决方法2
def out():
    # 定义a为一个列表
    a = [1]
    def inner():
        # 在执行时在inner()内未找到a的定义,但是在外部函数空间找到a[0]为list的定义
        a[0]= a[0]+1
        return a
    return inner

t = out()
print('解决方法2:',t())
type(t())# 注意:此时输出的t的类型为list
解决方法1: 2
解决方法2: [2]





list
'''
闭包在循环体中的使用:
'''

# 错误示例
flist = []

for i in range(3):
    print('for START')
    print('FOO START')
    def foo(x):
        print('foo running')
        print(x + i)
        print('foo run over')
    print('FOO END')
    print('i is : ', i)
    flist.append(foo)
    print('for END')
    
    
for f in flist:
    f(2) # 此时输出为4 4 4
# 原因是在执行for是遇到foo这一函数定义,只录入了foo(x)名,而没执行foo(x)的函数体
for START
FOO START
FOO END
i is :  0
for END
for START
FOO START
FOO END
i is :  1
for END
for START
FOO START
FOO END
i is :  2
for END
foo running
4
foo run over
foo running
4
foo run over
foo running
4
foo run over
'''对循环中使用闭包的正确用法'''

# 正确示例
flist = []

for i in range(3):
    print('for START')
    print('FOO START')
    def foo(x, y=i):
        print('foo running')
        print(x + y)
        print('foo run over')
    print('FOO END')
    print('i is : ',i)
    flist.append(foo)
    print('for END')
    
    
for f in flist:
    f(2) # 此时输出为2 3 4
# 在程序执行时将foo(x,y=i)录入,此时foo中的y=i是随着for函数一起执行的,在append到flist中的元素为
# [foo(x,y=0),foo(x,y=1),foo(x,y=2)]
# 在执行foo函数体中的内容的时候会有i的不同次序值,而不是最终的i
for START
FOO START
FOO END
i is :  0
for END
for START
FOO START
FOO END
i is :  1
for END
for START
FOO START
FOO END
i is :  2
for END
foo running
2
foo run over
foo running
3
foo run over
foo running
4
foo run over
闭包的作用
'''
1、持久化编程,保持住当前的运行环境
'''

# 跳棋 例子
origin = [0, 0]  # 坐标系统原点
legal_x = [0, 50]  # x轴方向的合法坐标
legal_y = [0, 50]  # y轴方向的合法坐标
def create(pos=origin):
    def player(direction,step):
        # 这里应该首先判断参数direction,step的合法性,
#         比如direction不能斜着走,step不能为负等
        # 然后还要对新生成的x,y坐标的合法性进行判断处理,
#     这里主要是想介绍闭包,就不详细写了。
        new_x = pos[0] + direction[0]*step
        new_y = pos[1] + direction[1]*step
        pos[0] = new_x
        pos[1] = new_y
        #注意!此处不能写成 pos = [new_x, new_y],原因在上文有说过
        return pos
    return player
 
player = create()  # 创建棋子player,起点为原点
print (player([1,0],10))  # 向x轴正方向移动10步
print (player([0,1],20))  # 向y轴正方向移动20步
print (player([-1,0],10))  # 向x轴负方向移动10步

[10, 0]
[10, 20]
[0, 20]
'''
2、根据外部作用域的局部变量来得到不同的结果
这有点像一种类似配置功能的作用,我们可以修改外部的变量,
闭包根据这个变量展现出不同的功能
'''
# 这是一个根据关键字过滤文件内容的简单闭包demo
# make_filter 中的keep是关键字
# 外部函数make_filter作用是设置关键字
# 内部函数the_filter是根据关键字过滤文件内容并输出相关内容
def make_filter(keep):
    def the_filter(file_name):
        with open(file_name,'r', encoding='utf-8') as file:
            lines = file.readlines()
        filter_doc = [i for i in lines if keep in i]
        return filter_doc
    return the_filter

# 获取文件《闭包用途2使用文档.txt》有关"闭包"的关键字
filter = make_filter("闭包")
filter_result = filter("./Gnerate_files/闭包用途2使用文档.txt")

for f in filter_result:
    print(f)

这是一个关于闭包用途的使用文档

但是我对原作者在循环中使用闭包的错误剖析有不同的见解,所以没有全部参考原作者的思路
装饰器

写代码的开放封闭原则

开放:对代码进行扩展开发
封闭:对代码已实现的功能,最好不要随意修改

语法糖:写一个函数,用@符号加在其他功能前,达到一个想要的结果

对装饰器有充分的理解要先掌握以下两点:

1、一切皆对象

2、闭包

装饰器的功能:

引入日志

函数执行时间统计

执行函数前预备处理

执行函数后清理功能

权限校验等场景

缓存

装饰器很好的实现了开放封闭原则

# 装饰器例子
def zsq(func):
    print('zsq print START')
    def prt():
        print('prt print'.center(10,"*"))
        func()
        print('{}执行完毕'.format(func.__name__))
    print('zsq print END')
    return prt

@zsq
def f1():
    print("这是一个f1函数".center(20,"*"))

def f2():
    print('这是f2函数')
    
# test
f1()

print('*'*18)

# 这里的f2 = zsq(f2) 和上面的@zsq作用是一样的
f2 = zsq(f2) # 这里将f2()作为参数,传入zsq()中的func
f2() # 这里的f2已经不是原来的函数了,而是zsq()中封装的prt函数

# 执行顺序为(二者顺序相同,这里以f1为例):
# 对于执行顺序,建议用断点调试的方法进行观察
# 1、zsq 函数头
# 2、func = f1 赋值操作
# 3、 f1函数头
#  4、zsq 函数体第一行,这里是print('zsq print START')
# 5、 记录prt函数头标记
#  6、prt()函数后紧跟的一行此例中为print('zsq print END)
# 7、prt函数体中的第一行,这里是('prt print'.center(10,"*"))
# 8、func() 在例子中也就是f1()
# 9、prt中func()后紧跟的一行
# 依次执行,直到执行完最后一行

# f1 为函数名
# f1() 为调用f1函数,只写f1不会调用f1函数
# 这里值得注意的是python执行文件中,遇到函数会先标记,然后继续执行函数后的内容,
# 最后执行函数的函数体
zsq print START
zsq print END
prt print*
******这是一个f1函数******
f1执行完毕
******************
zsq print START
zsq print END
prt print*
这是f2函数
f2执行完毕
# 多个装饰器 例子
def zsq1(f1):
    # 定义装饰器1
    print("the zsq1 is RUNING")
    def prt1():
        print('装饰器1'.center(10, '*'))
        return f1() # 回传传入的f1函数
    print("the zsq1 is END")
    return prt1 # 回传闭包内的函数名

def zsq2(f2):
    print("the zsq2 is RUNING")
    def prt2():
        print('装饰器2'.center(10,'*'))
        return f2()
    
    print("the zsq2 is END")
    return prt2

@zsq1
@zsq2 # 用zsq1()和zsq2()装饰test()
def test():
    print('test'.center(10, '*'))
    return 'hello world!'

# 测试
tmp = test()
print(tmp)
# 解释:
# python程序是顺序执行的,
# 装入顺序为取近优先,最靠近被装饰函数最先被装饰,并且函数在装饰时就已经开始运行了
# 例子中zsq2最靠近被装饰函数test(),所以test()函数先装入zsq2
# zsq2又被zsq1所装饰,所以zsq2要放入zsq1中
# 执行顺序为剥洋葱,由外向内
# 先执行zsq1中的闭包,然后是zsq2中的闭包(被装饰函数test()在zsq2函数的闭包中)
#######################
# 更加形象的例子就是把多个装饰器比作俄罗斯套娃
# 将被装饰函数看做最小的套娃,装饰器依据靠近被装饰函数的距离依次变大
# 在装饰器进行装饰时,可以看做装套娃:从最小的(这里是被装饰函数)开始,依次放入比自己大的娃娃中
# 在执行装饰器时,可以看做拆套娃:从最大的开始(这里是最外层的装饰器)拿,依次向内,直到取出最小的娃娃
the zsq2 is RUNING
the zsq2 is END
the zsq1 is RUNING
the zsq1 is END
***装饰器1***
***装饰器2***
***test***
hello world!
'''
装饰器执行的时间

Python解释器执行到@处时,就已经开始装饰了

装饰器对有参数,无参数函数进行装饰:

当无参时,不必特别处理,

当有参数时,对闭包中的函数进行设置形参,
这里就可以进行有参数的函数进行装饰了.

这里需要特别注意:
在有参数时,可以用不定长参数的方式,
*args和**kwargs,在调用装饰的函数时,
需要用同样的不定长参数进行解包

装饰器对带有返回值的函数进行装饰:

在闭包的函数中设置一个return 在调用被装饰的函数时,赋值,这样就可以输出
'''

# 对含定长参函数进行装饰 例子
print('对定长参数函数装饰')
def decorator_var(func):
    def decorator_var_in(a, b):
        print(a,'\t',b)
        func(a,b)
        
    return decorator_var_in

@decorator_var
def foo(a, b):
    print('sum = ', a+b)
    
foo(1,2)
        
print('定长装饰例子结束\n')
对定长参数函数装饰
1 	 2
sum =  3
定长装饰例子结束
# 对不定长参数函数装饰 例子
print('对不定长参数函数装饰')
def decorator_var(func):
    def decorator_var_in(*args, **kwargs):
        print(args,'\n',kwargs)
        func(*args, **kwargs)
        
    return decorator_var_in

@decorator_var
def foo(*args, **kwargs):
    l = [args, kwargs]
    print('set = :',l)
    
t = (1,2,3)
d = {
   'name':'sss','age':16}
foo(*t, **d)
        
print('不定定长装饰例子结束\n')
对不定长参数函数装饰
(1, 2, 3) 
 {'name': 'sss', 'age': 16}
set = : [(1, 2, 3), {'name': 'sss', 'age': 16}]
不定定长装饰例子结束
# 对带有返回值的函数进行装饰 例子
print('带有返回值的函数进行装饰')
def zsq(func):
    def bb():
        re = func()
        return re # 这里是注意点
    return bb
@zsq
def test():
    print("this is a test def !".center(30,"*"))
    return 666
ret = test()
# 注意这里的return
print(ret)
print('带有返回值的函数进行装饰结束')
带有返回值的函数进行装饰
*****this is a test def !*****
666
带有返回值的函数进行装饰结束
# 通用装饰器 例子
def decorator_pub(func):
    def decorator_in(*args, **kwargs):
        print("这是一个通用装饰器")
        print("args is {}\nkwargs is {}".format(*args, **kwargs))
        tmp = func(*args, **kwargs)
        return tmp
        #注意,在Python中,如果return 返回的是None,那么不算是错误,
#         所以,在这里一直写上return 是不算错的
    return decorator_in

@decorator_pub
def test(a,b):
    print("this is a test")
    return a+b

ret = test('a','c')
print(ret)
这是一个通用装饰器
args is ('a', 'c')
kwargs is {}
this is a test
ac
带有参数的装饰器

装饰器带参数,在原有的装饰器的基础上,设置外部变量

这里的设置外部变量就是在原有的装饰器的基础上,在外部再加一个带参数的函数

带有参数的装饰器能起到在运行时使用不同的功能

# 带参数的装饰器 例子
def func_arg(tmp):
    print("the value is {}".format(tmp))
    
    def zsq(func):
        print("zsq")
        def bb():
            print("bb")
            func()
        return bb
    
    return zsq

@func_arg(6666) # python执行到这里时,先执行了func_arg(tmp = 6666)
def test():
    print("this is test")

test()

print('\n我是分隔符\n')

def demo():
    print('this is demo')
    
demo = func_arg('11111')(demo)
demo()
# test的形式和demo的形式等价
the value is 6666
zsq
bb
this is test

我是分隔符

the value is 11111
zsq
bb
this is demo
类做装饰器

用类做装饰器需要在类中定义一个__call__()方法

# 类做装饰器 例子
class Demo(object):                                               
        def __init__(self, func):
            print("初始化{}".format(func.__name__))
            self.__func = func
        def __call__(self):
            print("这是类装饰器")
            self.__func()


@Demo
def test():
    print("test".center(20,"*"))
    
test()


初始化test
这是类装饰器
********test********
wraps函数

用于消除装饰器在装饰函数时改变了被装饰函数的说明文档这一缺点

# 未使用warps() 例子
import functools

print('未使用warps() 例子')

def zsq(func):
    "这是一个装饰器"
#     @functools.wraps(func)

    def a():
        '这是装饰器的内部函数'
        print("这里添加了一个装饰器")
        func()
        
    return a

@zsq
def test():
    "这里是一个测试函数"
    print("this is a test")
    
test()

# 输出test()的文档
print(test.__doc__)

未使用warps() 例子
这里添加了一个装饰器
this is a test
这是装饰器的内部函数
import functools

print('\n使用warps() 例子')

def zsq(func):
    "这是一个装饰器"
    @functools.wraps(func)
    def a():
        '这是装饰器的内部函数'
        print("这里添加了一个装饰器")
        func()
        
    return a

@zsq
def test():
    "这里是一个测试函数"
    print("this is a test")
    
test()

print(test.__doc__)
使用warps() 例子
这里添加了一个装饰器
this is a test
这里是一个测试函数
装饰器使用场景
'''授权(Authorization)'''

# 导入wraps防止说明文档被覆盖
from functools import wraps

def requires_auth(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        auth = request.authorization
        
        if not auth or not chech_auth(auth.username, auth.password):
            authenticate()
            
        return f(*args, **kwargs)
    
    return decorated
'''日志(Logging)'''

# 导入wraps防止说明文档被覆盖
from functools import wraps
def logit(func):
    @wraps(func)
    
    def with_logging(*args, **kwargs):
        print(func.__name__ + 'wass called')
        return func(*args, **kwargs)
    
    return with_logging

@logit
def addition_func(x):
    '''Do some math.'''
    return x + x

result = addition_func(4)
# output: addition_funcwass called
addition_funcwass called
'''在函数中嵌入装饰器(相当于带参数的装饰器)'''

# 记录日志并输出到日志文件
from functools import wraps

def logit(logfile='./Gnerate_files/out.log'):
    def logging_decorator(func):
        @wraps(func)
        def wrapped_function(*args, **kwargs):
            log_string = func.__name__+' was called'
            print(log_string)
            # 打开logfile,写入日志
            with open(logfile, 'a+', encoding='utf-8') as log_file:
                # 写入日志
                log_file.write(log_string + '\n')
            return func(*args, **kwargs)
        return wrapped_function
    return logging_decorator
    
@logit()
def myFunc1():
    pass


@logit(logfile='./Gnerate_files/func2.log')
def myFunc2():
    pass

# 测试
myFunc1()
# 输出myFunc1 was called
# 并且生成一个out.log文件,文件内容为上述字符串
myFunc2()
# 输出myFunc2 was called
# 并且生成一个out.log文件,文件内容为上述字符串
myFunc1 was called
myFunc2 was called

模块

'''
os.__file__

__file__:用于显示当前文件所在的绝对路径

import os

xxx-cpython-35.pyc 表示c语言编写的Python编译器3.5版本的字节码

import Name

from name import defName,defName2

from name import * 注意:这里尽量不要使用这种方法导入;

使用这种方式导入,若存在同名函数,后导入的函数会覆盖先导入的函数

import Name as sName

__name__属性

在模块被调用时不希望调用模块中的某些功能可是使用"__name__"属性来实现

例子:
if __name__ == '__main__':
    print('在本体模块内被调用')
else:
    print('在其他模块内被调用')
例子结束

__all__属性

在模块被导入时的所有方法名
所有在模块被调用的方法名都存在__all__[]中

__all__属性的功能还可用dir([x])来实现

dir()函数会罗列当前定义的所有名称

并不是所有模块都有"__all__"属性

程序执行时导入模块路径:
import sys

sys.path.append('/home/itcast/xxx')
# 末尾追加路径
sys.path.insert(0, '/home/itcast/xxx') 
#头部添加路径(可以确保先搜索这个路径)
'''
# 程序执行时添加路径 例子
import sys

raw_list = sys.path

sys.path.append('D:\\Documents\\Jupyter_notebook')

append_list = sys.path

sys.path.insert(0, 'D:\\Documents')

insert_list = sys.path

print('raw_list = {}\n\nappend_list = {}\n\ninsert_list = {}'.format(
    raw_list,append_list,insert_list
))
raw_list = ['D:\\Documents', '', 'D:\\Documents\\Jupyter_notebook', 'C:\\MyPrograms\\Anaconda3\\python37.zip', 'C:\\MyPrograms\\Anaconda3\\DLLs', 'C:\\MyPrograms\\Anaconda3\\lib', 'C:\\MyPrograms\\Anaconda3', 'C:\\MyPrograms\\Anaconda3\\lib\\site-packages', 'C:\\MyPrograms\\Anaconda3\\lib\\site-packages\\win32', 'C:\\MyPrograms\\Anaconda3\\lib\\site-packages\\win32\\lib', 'C:\\MyPrograms\\Anaconda3\\lib\\site-packages\\Pythonwin', 'C:\\MyPrograms\\Anaconda3\\lib\\site-packages\\IPython\\extensions', 'C:\\Users\\shj\\.ipython', 'D:\\Documents\\Jupyter_notebook']

append_list = ['D:\\Documents', '', 'D:\\Documents\\Jupyter_notebook', 'C:\\MyPrograms\\Anaconda3\\python37.zip', 'C:\\MyPrograms\\Anaconda3\\DLLs', 'C:\\MyPrograms\\Anaconda3\\lib', 'C:\\MyPrograms\\Anaconda3', 'C:\\MyPrograms\\Anaconda3\\lib\\site-packages', 'C:\\MyPrograms\\Anaconda3\\lib\\site-packages\\win32', 'C:\\MyPrograms\\Anaconda3\\lib\\site-packages\\win32\\lib', 'C:\\MyPrograms\\Anaconda3\\lib\\site-packages\\Pythonwin', 'C:\\MyPrograms\\Anaconda3\\lib\\site-packages\\IPython\\extensions', 'C:\\Users\\shj\\.ipython', 'D:\\Documents\\Jupyter_notebook']

insert_list = ['D:\\Documents', '', 'D:\\Documents\\Jupyter_notebook', 'C:\\MyPrograms\\Anaconda3\\python37.zip', 'C:\\MyPrograms\\Anaconda3\\DLLs', 'C:\\MyPrograms\\Anaconda3\\lib', 'C:\\MyPrograms\\Anaconda3', 'C:\\MyPrograms\\Anaconda3\\lib\\site-packages', 'C:\\MyPrograms\\Anaconda3\\lib\\site-packages\\win32', 'C:\\MyPrograms\\Anaconda3\\lib\\site-packages\\win32\\lib', 'C:\\MyPrograms\\Anaconda3\\lib\\site-packages\\Pythonwin', 'C:\\MyPrograms\\Anaconda3\\lib\\site-packages\\IPython\\extensions', 'C:\\Users\\shj\\.ipython', 'D:\\Documents\\Jupyter_notebook']
# __all__和dir() 比较例子
print('this is a example for __all_ and dir()')
import os
A=os.__all__
B=dir(os)
print('this is __all__:',A)
print('\n***\n'*2)
print('this is dir(): ',A)
print('\n***\n'*2)
C=list(set(A).difference(set(B)))
print('this is difference of __all__ and dir()', C)

this is a example for __all_ and dir()
this is __all__: ['altsep', 'curdir', 'pardir', 'sep', 'pathsep', 'linesep', 'defpath', 'name', 'path', 'devnull', 'SEEK_SET', 'SEEK_CUR', 'SEEK_END', 'fsencode', 'fsdecode', 'get_exec_path', 'fdopen', 'popen', 'extsep', '_exit', 'DirEntry', 'F_OK', 'O_APPEND', 'O_BINARY', 'O_CREAT', 'O_EXCL', 'O_NOINHERIT', 'O_RANDOM', 'O_RDONLY', 'O_RDWR', 'O_SEQUENTIAL', 'O_SHORT_LIVED', 'O_TEMPORARY', 'O_TEXT', 'O_TRUNC', 'O_WRONLY', 'P_DETACH', 'P_NOWAIT', 'P_NOWAITO', 'P_OVERLAY', 'P_WAIT', 'R_OK', 'TMP_MAX', 'W_OK', 'X_OK', 'abort', 'access', 'chdir', 'chmod', 'close', 'closerange', 'cpu_count', 'device_encoding', 'dup', 'dup2', 'environ', 'error', 'execv', 'execve', 'fspath', 'fstat', 'fsync', 'ftruncate', 'get_handle_inheritable', 'get_inheritable', 'get_terminal_size', 'getcwd', 'getcwdb', 'getlogin', 'getpid', 'getppid', 'isatty', 'kill', 'link', 'listdir', 'lseek', 'lstat', 'mkdir', 'open', 'pipe', 'putenv', 'read', 'readlink', 'remove', 'rename', 'replace', 'rmdir', 'scandir', 'set_handle_inheritable', 'set_inheritable', 'spawnv', 'spawnve', 'startfile', 'stat', 'stat_result', 'statvfs_result', 'strerror', 'symlink', 'system', 'terminal_size', 'times', 'times_result', 'truncate', 'umask', 'uname_result', 'unlink', 'urandom', 'utime', 'waitpid', 'write', 'makedirs', 'removedirs', 'renames', 'walk', 'execl', 'execle', 'execlp', 'execlpe', 'execvp', 'execvpe', 'getenv', 'supports_bytes_environ', 'spawnl', 'spawnle']

***

***

this is dir():  ['altsep', 'curdir', 'pardir', 'sep', 'pathsep', 'linesep', 'defpath', 'name', 'path', 'devnull', 'SEEK_SET', 'SEEK_CUR', 'SEEK_END', 'fsencode', 'fsdecode', 'get_exec_path', 'fdopen', 'popen', 'extsep', '_exit', 'DirEntry', 'F_OK', 'O_APPEND', 'O_BINARY', 'O_CREAT', 'O_EXCL', 'O_NOINHERIT', 'O_RANDOM', 'O_RDONLY', 'O_RDWR', 'O_SEQUENTIAL', 'O_SHORT_LIVED', 'O_TEMPORARY', 'O_TEXT', 'O_TRUNC', 'O_WRONLY', 'P_DETACH', 'P_NOWAIT', 'P_NOWAITO', 'P_OVERLAY', 'P_WAIT', 'R_OK', 'TMP_MAX', 'W_OK', 'X_OK', 'abort', 'access', 'chdir', 'chmod', 'close', 'closerange', 'cpu_count', 'device_encoding', 'dup', 'dup2', 'environ', 'error', 'execv', 'execve', 'fspath', 'fstat', 'fsync', 'ftruncate', 'get_handle_inheritable', 'get_inheritable', 'get_terminal_size', 'getcwd', 'getcwdb', 'getlogin', 'getpid', 'getppid', 'isatty', 'kill', 'link', 'listdir', 'lseek', 'lstat', 'mkdir', 'open', 'pipe', 'putenv', 'read', 'readlink', 'remove', 'rename', 'replace', 'rmdir', 'scandir', 'set_handle_inheritable', 'set_inheritable', 'spawnv', 'spawnve', 'startfile', 'stat', 'stat_result', 'statvfs_result', 'strerror', 'symlink', 'system', 'terminal_size', 'times', 'times_result', 'truncate', 'umask', 'uname_result', 'unlink', 'urandom', 'utime', 'waitpid', 'write', 'makedirs', 'removedirs', 'renames', 'walk', 'execl', 'execle', 'execlp', 'execlpe', 'execvp', 'execvpe', 'getenv', 'supports_bytes_environ', 'spawnl', 'spawnle']

***

***

this is difference of __all__ and dir() []
#dir() 例子

dir()
['In',
 'Out',
 '_',
 '__',
 '___',
 '__builtin__',
 '__builtins__',
 '__doc__',
 '__loader__',
 '__name__',
 '__package__',
 '__spec__',
 '_dh',
 '_i',
 '_i1',
 '_i10',
 '_i11',
 '_i12',
 '_i13',
 '_i14',
 '_i15',
 '_i16',
 '_i17',
 '_i18',
 '_i19',
 '_i2',
 '_i20',
 '_i3',
 '_i4',
 '_i5',
 '_i6',
 '_i7',
 '_i8',
 '_i9',
 '_ih',
 '_ii',
 '_iii',
 '_oh',
 'a',
 'add',
 'alist',
 'astring',
 'exit',
 'get_ipython',
 'i',
 'is_odd',
 'l',
 'newlist',
 'numlist',
 'produce',
 'quit',
 'reduce',
 'sort_list',
 'sorted_str',
 'sum']
os模块
'''
os.access(path,mode) 

检查权限;path:路径;mode{
os.F_OK: 作为access()的mode参数,测试path是否存在。最常用
os.R_OK: 包含在access()的mode参数中 , 测试path是否可读。
os.W_OK 包含在access()的mode参数中 , 测试path是否可写。
os.X_OK 包含在access()的mode参数中 ,测试path是否可执行。
}

os.chdir(path) 改变当前工作目录

os.chmod(path,mode) 更改权限

os.chown(path, uid, gid) 更改文件所有者

os.chroot(path) 改变当前进程的根目录

os.path.realpath(__file__) 返回真实路径

os.path.split() 返回路径的目录和文件名

os.getcwd() 得到当前工作的目录

__file__ 是用来获得模块所在的路径的 

更多参照下方的help

'''
import os
dir(os)
['DirEntry',
 'F_OK',
 'MutableMapping',
 'O_APPEND',
 'O_BINARY',
 'O_CREAT',
 'O_EXCL',
 'O_NOINHERIT',
 'O_RANDOM',
 'O_RDONLY',
 'O_RDWR',
 'O_SEQUENTIAL',
 'O_SHORT_LIVED',
 'O_TEMPORARY',
 'O_TEXT',
 'O_TRUNC',
 'O_WRONLY',
 'P_DETACH',
 'P_NOWAIT',
 'P_NOWAITO',
 'P_OVERLAY',
 'P_WAIT',
 'PathLike',
 'R_OK',
 'SEEK_CUR',
 'SEEK_END',
 'SEEK_SET',
 'TMP_MAX',
 'W_OK',
 'X_OK',
 '_Environ',
 '__all__',
 '__builtins__',
 '__cached__',
 '__doc__',
 '__file__',
 '__loader__',
 '__name__',
 '__package__',
 '__spec__',
 '_execvpe

本文标签: 学习笔记INDEX