python学习笔记

python

地址

  1. mac 下python 2.7的地址
    /Library/Python/2.7/
    3.6
    /Library/Frameworks/Python.framework/Versions/3.6/

    • 避免循环导入依赖的方法 依赖放在最后面

正则表达式

+表示至少一个字符
{n}表示n个字符
*表示任意个字符

?表示0个或一个字符

.可以匹配任何字符

\w匹配字母
\d匹配数字
\s匹配一个空格

r代表正则表达式

^表示行的开头,$表示行的结束

\d \w 必 须 以 数 字 结 束 \w 必须以字母结束

多加一个\代表转义字符
‘ABC\-001’

匹配:abc\001

\d{3} 可以匹配:010, 230,123
\s+ 表示至少一个空格
\s{4}表示至少4个空格

\d{3,8} 表示3到8个数字

\d{3}\s+\d{3,8}
\d{3} 三个数字,\s匹配一个空格 \d{3-8}3-8个数字

进阶

[0-9a-zA-Z_] 匹配一个数字,一个字母,或者下划线
[0-9a-zA-Z_]+ 匹配至少由一个数字字母或者下划线组成的字符串
[a-zA-Z_][0-9a-zA-Z_]匹配由字母或者下划线开头,后接任意个由一个数字,字母,下划线组成的字符串

方法

  • match 表示是否匹配,如果匹配 返回match对象,否则返回None

  • split() 方法用于切割
    ‘ab c’.split(’ ‘)

  • finditer :

    返回string中所有与pattern相匹配的全部字串,返回形式为迭代器。

提取子字符串

sd=re.match(r’^(\d{3})-(\d{6})’,’021-2345678’)

输出第几组函数

print(sd.group(1))
输出第一组函数

替换字符串

re.sub

path = re.sub(‘[_]’, ‘/’, url1)
将_全部替换为/

|是或的意思,匹配到两个的任何一个都行

sd=re.compile(‘

预编译

正则表达式每次使用都要编译
所以先预编译一下

两个字符串 或匹配

sd=re.compile(‘/places/default/(index|view)/.*?[\d]$’)

正则Demo

find_id = re.compile('\w{0,5}-\w{0,5}-\w{0,7}-\d{0,3}')

str='fan-jia-liang-57'

numpy函数:

1.shape函数:计算数组大小
2.mat函数 将目标数据转换为矩阵
3.zero 函数 将数组初始化为0
4.numpy.array将list转换为numpy的数组
5.random ranint 取随机数
6.去掉字符串最后的换行符:line=line[:-1]
7.numpy比较两个array是否全部相同, if(arry1==array2).all()
print(true)

python读取文件的三种方法:

  • f = open(“foo.txt”) # 返回一个文件对象
    line = f.
    adline() # 调用文件的 readline()方法
    while line:
    print line, # 后面跟 ‘,’ 将忽略换行符

    print(line, end = ”)   # 在 Python 3中使用

    line = f.readline()
    f.close()

  • for line in open(“foo.txt”):
    print line,

  • f = open(“c:\1.txt”,”r”)
    lines = f.readlines()#读取全部内容
    for line in lines
    print line
    python 往txt写内容:
    with open(‘a.txt’,’w’) as f:
    for i in a:
    f.write(i)

    python 字符乱码问题

字符串编码

encoding 将str转换为机器码

decoding 将机器码转换为str

plt 乱码

  • 在/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages下

  • 在py中加 plt.rcParams[‘font.sans-serif’]=[‘SimHei’]将simhei字体下载放在pyplot中即可解决乱码

requests乱码

list

  • list.index()求元素的下标

  • str list和 int list 互相转换 nums=[int (i) for i in nums]

  • s = re.findall(“\d+”,nums)找出字符串中所有数字

  • list1 = [“这”, “是”, “一个”, “测试”]
    for index, content in enumerate(list1):
    print (index)
    print (content)

  • 元组转List tuple =list(tuple)

  • list 去除重复元素
    list=set(list)

  • 查找元素
    a.index(s) 查找s元素的下标位置

  • 逆序输出list

    reversed(a)

  • list的复制

    import copy
    a=[123,234,677]
    b=a[:]
    print(b)
    
    c=copy.deepcopy(a)
    print(c)

tuple

  1. 对于不可变类型,不管是深拷贝还是浅拷贝,都只是创建一个引用
  2. 元组为不可变类型
  3. 对于str类型,如果两个str相同,那么是is和=的,这是python的优化方法,善意的谎言。。。
  4. 在小的整数上也会采取这种措施 停留interning
  5. 5.

dict

散列方法

获得dict[key]的值,首先调用hash(key)来计算key的散列值,把这个值的低几位数字作为偏移量,

在散列表中查找表元,如果表元是空的,就抛出异常。 如果不为空,则检查key是否等于found_key

如果相等则返回结果。

如果不相等,发生散列冲突,发生的原因:在寻找元素值时,如果发生了冲突,算法会在散列值中另外取几位。

然后将新得到的数字当做索引来寻找表元。 如果找到的为空,抛出keyerror,如果冲突,重复刚才步骤

带来的后果

dict 的key值必须是可散列的, 也就是说是固定不变的,str,bytes 还有数字类型
消耗的空间比较大
键值的查询很快

键值的次序取决于添加顺序

对于不存在的dict 会抛出keyerror,解决方法:重写missing方法

  • 字典sd, 设置元素sd[i]=i,得到元素 sd.getvalue(i)

  • 储存
    like_dict[‘a’]=we

  • 得到dict类型的key和value

    print(dict.keys())

    print(dict.values())

  • 遍历字典

    for (k,v) in dict.items()

    1. list 和tuple 的相同点和不同点

      • list和tuple 可以相互转换,list可变,tuple不可变

      • tuple比list更快更安全

      • tuple是可以hash的,list不行

    2. dict的内部实现,算法的实现 tuple 和list作为dict 的key值有什么问题:

    3. python的多进程,协程实现和多线程 GIL全局锁

    查看dict 是否有某个key值 dict.get(key)

  • 字典的复制 dict.copy()

  • python字符串反转 str[::-1]

  • extends 函数
    a=[1,2,3,4]
    b=[1,2,3,4,5]
    a.extend(b for i in b not in a)
    a=[1,2,3,4,1,2,3,4,5]

字典

20.判断一个属性是否在字典中 print d.has_key(‘site’) if ‘sa’ in dic.keys(): 应该用后面的,python3不能用前面的了?

21: if value[i].get(each[i]) == None:
value[i][each[i]] = 1
else:
value[i][each[i]] += 1

22.import sys   sys.version  import django  django.VERSION 查看各种安装包的版本

23.启动ipython python3 -m IPython notebook


python 的魔法函数

list

__set__item():
__get__item():
_ len _ 求元素的长度
__delete_item()
通过类似于list的用法,实现修改和插入。 通过对方法的重写,方便

function

repr _ 将对象用字符串表示出来,如果没实现,输出类似于

下划线

单下划线,私有变量 不能通过导入来调用

双下划线,受保护变量 子类也不能调用

前后下划线: 系统定义的名字

函数式编程

map(func,rang(2)) 将func函数的返回值写入list,然后将list返回

print reduce(lambda x, y: x * y, range(1, 5)) 将1,2传入然后计算出结果,x=2,y=3,然后将结果给x,再找一个数给


pickle

1.pickle存中文字符
pickle.dump(json.dumps(data,ensure_ascii=False),output)

  1. pickle 写文件时必须指定文件名

I/O操作

按行读取

with open('A.csv','rb') as csvfile:
     reader = csv.reader(csvfile)
     rows = [row for row in reader] print rows

一次读取为str

with open(‘html.txt’,’r’) as opener:
html=opener.read()

按行读取,忽略首行元素

headers=next(reader)

追加写入csv文件

with open(“filename.csv”,”a+”) as csvfile:
rU 或 Ua 以读方式打开, 同时提供通用换行符支持 (PEP 278)
a+表示追加写入
w 以写方式打开,
a 以追加模式打开 (从 EOF 开始, 必要时创建新文件)
r+ 以读写模式打开
w+ 以读写模式打s开 (参见 w )
a+ 以读写模式打开 (参见 a )
rb 以二进制读模式打开
wb 以二进制写模式打开 (参见 w )
ab 以二进制追加模式打开 (参见 a )
rb+ 以二进制读写模式打开 (参见 r+ )
wb+ 以二进制读写模式打开 (参见 w+ )
ab+ 以二进制读写模式打开 (参见 a+ )

csv

将list写入csv文件
writer=csv.writer(open(‘ip_message.csv’,’w’))

按行写入

writer.writerow(fields)
for i in result:
writer.writerow((i,result[i]))

将dict 写入csv文件

with open('dict.csv', 'wb') as csv_file:
    writer = csv.writer(csv_file)
    for key, value in mydict.items():
       writer.writerow([key, value])

将tuple 写入csv

def write_in_csv(tuple):
    with open('message.csv', 'a')as opener:
        writers=csv.writer(opener)
        writers.writerow(tuple)

文件目录和文件读写

print(__file__)
print(os.path.abspath(__file__))
上面文件目录
path=os.path.abspath(os.path.dirname(__file__))
image_path=os.path.join(path,'dataset')
# 将目录下文件名转换为List
file=os.listdir(image_path)

yeild

回调函数

将一个函数以参数形式传到另一个函数中


输出

输出格式

print (‘a%sb%s’%(a,b))

format

print(‘好的代理:{}’.format(each))

多个format

print(“sd{1}{0}”.format(b,a))

———-https://www.baidu.com/s?wd=14.118.254.90

将变量放在字符串中输出

cc=China
url='{}/{cc}/{cc}.gif'.format(BASE_URL,cc=cc.lower())
http://flupy.org/data/flags/china/china.gif

不换行输出

pyhton2:

编码

中文无法显示的话
i.decode(encoding=’utf-8’)


Exception

raise

类似于java 中的throw 可以根据情况自己抛出异常

if response.code==200:
raise RuntimeError(“wwe”)
except RuntimeError as e:
print(e.args)

ValueError 数据转换异常
IndexError 数组下标异常
在异常中加的参数作为args参数

自定义异常类

class OutboundsError(Exception):
def init(self,errormsg):
self.errormsg=errormsg
def str(self):
print(“调用了这里”)
return self.errormsg
当打印对象时会调用 _ str_ 方法

except

多个异常:

(KeyError,FilenotFoundError) as e:

配置logging

首先new一个handler

RotatingFileHandler

然后添加到app.logger


日期和日历

datetime

 a = datetime(2012, 9, 23)

from datetime import datetime
获得过几天的日期
yesterday = today - datetime.timedelta(days=1) #用今天日期减掉时间差,参数为1天,获得昨天的日期
tomorrow = today + datetime.timedelta(days=1) #用今天日期加上时间差,参数为1天,获得明天的日期
print(afterday.year)
print(afterday.month)
print(afterday.day)


神奇的函数

lambda 表达式的学习

a=[1,2,3,4]
g=lambda x:x**2
for each in a:
print(g(each))

pydoc3 -p:5000 在5000端口查看消息

根据 字母表获得 所有字母

a=[chr(i) for i in rang(97,123)]

ord(a)=97

sys.argv[1]

在console导入路径或者py文件

import sys

sys.path.append(“/path/to/your/test.py”)

迭代器

a=iter(a)
print(next(a))

next函数,返回迭代器的下一个对象

并发

并发是指一次处理多件事。

并行是指一次做多件事。

二者不同,但是有联系。

一个关于结构,一个关于执行。

并发用于制定方案,用来解决可能(但未必)并行的问题。

yield

协程

def simple_coroutine():
    print('corroutine is start')
    x=yield
    print('corrountine reeived',x)

mycoro=simple_coroutine()
print mycoro

next(mycoro)
#向yield发送一个值,输出x为23
mycoro.send(23)
先要调用next函数,作为预激协程的指令,让协程跳转到第一个yield表达式 产出变量的初始值None

next函数可以包装为装饰器

def start(func):
    def star(*args,**kwargs):
        sd=func(*args,**kwargs)
        next(sd)
        return sd
    return star

个人体会:通过send语句将值传递给yield对象

执行下一个yield让协程进入下一个状态

当执行完后,协程为yield状态

python3 查看生成器状态:

from inspect import getgeneratorstate

协程来处理异常类:

如果传入的异常无法处理,协程就会终止

协程的四个状态:

gen_created: 等待开始执行 (只有在多线程应用中才能看到)

gen_running:解释器正在执行

gen_suspended:在yield表达式处暂停

gen_closed 执行结束

类似于return 的关键字,返回的类型为生成器

不过不会直接退出函数

而是等到 循环结束,返回一个list

yield from

可以简化yield语法

GIL

global interpreter lock 全局解释锁

一次只能有一个线程在运行

gIL对io密集型任务 的影响很小

Python 标准库中的所有阻塞型 I/O 函数都会释放 GIL,允许其他线程运

行。time.sleep() 函数也会释放 GIL。因此,尽管有 GIL,Python 线程还是能在 I/O

密集型应用中发挥作用

当某个线程在等待I/O时,python调度程序会切换到另一个线程

ProcessPool 使用了多进程来绕开多线程

cpu密集

ProcessPoolExecutor 多进程的 多少个核就有多少个进程

multiprocessing 绕开GIL

python-parallelize库

定义一个python-parallelize 装饰器,可以应用到任何函数上

生成器: 类似于链表推导,

只不过只会放入内存一次

也就是说只能输出一次,用完就没了

*args,**kwargs

*args是tuple
**kwrgs是dict

def play(*args,**kwargs):
print(args)
print(kwargs)
(2, 3)
{‘age’: 3, ‘name’: 2}

play(2,3,name=2,age=3)

filter 函数

过滤函数?
- a=range(10)
print(filter(lambda x:x>3,a))

random

values=[1,2,3,4]
- random.choice
random.choice(values)
从List中随机选择元素

  • 提取出n个不同的样本
    random.sample(values,2)

  • random 打乱顺序
    random.shuffle(values)

  • 生产随机整数
    random.randint(0,10)

  • 生成0-1 范围内均匀分布的浮点数
    random.random()

  • 生成n位随机二进制整数
    random.getrandbits(200)

运算符

& 按位运算符 取交集
| 按位运算符 取并集
^ 当二进制位不相等时,取1
~ 按位取反
<< 左移运算符 高位丢弃,低位补0

右移,低位丢弃,高位补0

生成器

节省内存

pos = (n for n in mylist if n > 0)
for each in pos:
    print each
  • 列表推导
    b=[for each in b if b>0] //占用内存比较多
  • 求list中最大的元素
    print(max(mylist))
  • chr(97)-> a 输入数字,输出字母
  • join 函数, b.join(a) b加入a中 每个b加入到a的每个元素中
    a=”sbv” b=”-” c=b.join(a)
    print(c)
  • xrange返回的为xrange类型,本质为生成器,性能不会放入内存

input

input 会自动判断类型
raw_input不会

input 输入不能有空格
raw_ input可以
还是raw_input合适点

id

查看变量地址空间

isinstance和type的区别

isinstance 是广义上的判断,可以根据父类来判断


面向对象

继承

构造方法的初始化

class A:
    def spam(self):
        print('A.spam')

class B(A):
    def spam(self):
        print('B.spam')
        super().spam()  # Call parent spam()

抽象类

装饰器

装饰器是可调用对象,其参数是另一个函数

不改变函数的前提下,增强函数的功能

在导入时执行调用

  1. @property
    将方法变为属性

本质是为了增加原的功能。
将原函数作为参数传到另一个函数中
相当于方法套了一层方法。
def identify(f):
print(f())
return ()
def foo():
return ‘bar’
identify(foo)
上面等价于:
def identify(f):
print(f())
@identify
def foo():
return “sd”

闭包;

一些坑

  • a//2 还是int 类型 a/=2 就是float类型

pip

  • pip list –outdate
    列出所有可以升级的软件

  • pip install –upgrade requests
    升级一个包

  • 升级所有可用的包

    for i in pip list -o --format legacy|awk '{print $1}' ; do pip install –upgrade $i; done

OS

_ file _ 属性为当前py文件的路径

execv(file,args)

execv()执行一个新的程序,用新的程序代替子进程的空间

面试问题

  1. 深拷贝和浅拷贝的区别 深拷贝和浅拷贝复制一个对象,然后把之前的对象删掉,引用技术应该怎么变

  2. 对一个对象进行如何操作才能使他的引用计数增加或者减少

  3. python垃圾回收机制

  4. 复制一个list的方法

  5. python内部list和tuple的实现的数据结构 数组

  6. 数据库索引,b树和b+树的实现和区别,为什么不用红黑树

  7. ping的端口号 基于什么协议的

    基于iCMP协议,没有端口号 控制报文协议

  8. python _ init 方法和 _ new _的区别

    new: 创造对象是调用,会返回当前对象的一个实例

    init: 创造完对象后调用,无返回值

    同时存在,会优先调用new方法

    new_是静态方法,init是实例方法

  9. python的闭包函数 变量在闭包中调用的次序

  10. 每行大小为16个字节,总共1G大小的文件,限制内存1MB,找出频率出现次数最多的单词

    解决方法: 1mb内存可以处理 2^16次方个单词,首先进行切分为100个文件,然后

  11. 如何从一个很长的字符串来找一个子字符串 KMP算法

哪些是可变类型

哪些是不可变类型

深拷贝和浅拷贝的区别

装饰器的特点

装饰器有哪些优点

  1. 便于开发
  2. 便于代码复用
  3. 3.

python语言内部

内存管理

  1. 引用计数

将一个对象放入列表中,引用增加

分配一个新的名称,引用增加

引用计数减少: 显式的销毁

sys.getrefcount( )函数可以获得对象的当前引用计数

  1. 垃圾回收

    当引用计数清零时,垃圾回收机制

  2. == 和is 的区别

    ==比较对象的数据,is比较对象的标识(id)

  3. copy和deepcopy

    copy了后,内部对象的引用还没有变,仅仅是复制了表面

    deepcopy是递归复制,完全是两个不同的对象

  4. numpy就是一个很好地例子,它的运行速度真的非常快,因为很多算术运算其实并不是通过Python实现的。

  5. 答:“猴子补丁”就是指,在函数或对象已经定义之后,再去改变它们的行为。

  6. 偶尔也会出现引用循环(reference cycle)。垃圾回收器会定时寻找这个循环,并将其回收。举个例子,假设有两个对象o1和o2,而且符合o1.x == o2和o2.x == o1这两个条件。如果o1和o2没有其他代码引用,那么它们就不应该继续存在。但它们的引用计数都是1。

  7. 答:print的输出是标准输出,可以指向任何可以输出的流,包括http输出

  8. 闭包: 外部函数的返回值必须是内嵌函数,可以通过外部函数的返回值来继续调用内嵌函数,推迟函数的

鸭子类型:

走起路来像鸭子,只关心行为

又比如list.extend()方法中,我们并不关心它的参数是不是list,只要它是可迭代的,所以它的参数可以是list/tuple/dict/字符串/生成器等.

你可能感兴趣的:(学习记录,IceCola的学习笔记)