重置未完

# requests

# 请求

基本用法:

1752569378667

r.text 就是整个响应。get 传的参数直接写 url 里,或者传个字典 (params=...)。

1752569655358

type (r.text) 为 str,且是 json 格式(反正不是就会报错,试一试总是好的.jpg),可以使用 r.json (),将其转化为字典。

其他方法:

1752569426753

post 传参此时就只能传字典,data=...

在请求体中位于 form 部分

# 设置请求头

也是传字典,headers=...

1752570267683

# 响应

1752571661968

其中 r.context 就是网页源码

# 爬取二进制数据

网页上传输的非文本都是用的二进制编码,所以可以来爬取它们

import requests
r=requests.get('xxx')
with open('favicon.ico','wb') as f:
    f.write(r.content)

EX:一点其他的小应用:

读写文件

#写
with open('test.txt', 'w', encoding='utf-8') as f:   #f (ile) 是对象
    f.write('test')
#读
with open('test.txt', 'r', encoding='utf-8') as f:
    f.readlines()
#使用 with 会在执行完自动 close,避免忘记关闭

获取后缀

def getfile_fix(filename):
     return filename[filename.rfind('.')+1:]
print(getfile_fix('runoob.txt'))

检索后缀

import os
import os.path
#path = 'D:/UC/'
ls = []
def getAppointFile(path,ls):
    fileList = os.listdir(path)
    try:
        for tmp in fileList:
            pathTmp = os.path.join(path,tmp)
            if True==os.path.isdir(pathTmp):
                getAppointFile(pathTmp,ls)
            elif pathTmp[pathTmp.rfind('.')+1:].upper()=='PY':
                ls.append(pathTmp)
    except PermissionError:
        pass
def main():
    while True:
        path = input('请输入路径:').strip()
        if os.path.isdir(path) == True:
            break
    getAppointFile(path,ls)
    #print(len(ls))
    print(ls)
    print(len(ls))
main()

# threading

# 基本操作

import threading
import time
def print_numbers(xxx):
    print(xxx)
    for i in range(5):
        time.sleep(1)
        print(i)
# 创建线程 (类)
thread = threading.Thread(target=print_numbers,args=(temp,))
#参数必须是元组,所以如果单个参数,必须加,
# 启动线程
thread.start()
# 等待线程结束
thread.join()

1752584014773

该类的方法与属性:

1752584068488

例子:

#!/usr/bin/python3
import threading
import time
exitFlag = 0
class myThread (threading.Thread):   #继承
    def __init__(self, threadID, name, delay):  #子类构造函数
        threading.Thread.__init__(self)     #调用构造(初始化)函数,self 不可省略
        self.threadID = threadID            #add 成员
        self.name = name                    #add 成员
        self.delay = delay                  #add 成员
    def run(self):                          #当实例化的对象执行时执行
        print ("开始线程:" + self.name)
        print_time(self.name, self.delay, 5)
        print ("退出线程:" + self.name)
def print_time(threadName, delay, counter):
    while counter:
        if exitFlag:
            threadName.exit()
        time.sleep(delay)
        print ("%s: %s" % (threadName, time.ctime(time.time())))
        counter -= 1
# 创建新线程
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)
# 开启新线程
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print ("退出主线程")

# 线程同步

相比 C++,更加简洁,只有锁定和未锁定两组状态:

class myThread (threading.Thread):
    def __init__(self, threadID, name, delay):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.delay = delay
    def run(self):
        print ("开启线程: " + self.name)
        # 获取锁,用于线程同步
        threadLock.acquire()
        print_time(self.name, self.delay, 3)
        # 释放锁,开启下一个线程
        threadLock.release()
def print_time(threadName, delay, counter):
    while counter:
        time.sleep(delay)
        print ("%s: %s" % (threadName, time.ctime(time.time())))
        counter -= 1
threadLock = threading.Lock()    #创建锁对象
threads = []    #这个东西的作用其实是最后一起 join
# 创建新线程
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)
# 开启新线程
thread1.start()
thread2.start()
# 添加线程到线程列表
threads.append(thread1)
threads.append(thread2)
# 等待所有线程完成
for t in threads:
    t.join()
print ("退出主线程")

# 优先级队列

其实是只用一个锁就行,在多进程同时运行的完成任务(任务在队列里)的时候不需要每一个都锁然后释放

1752586244208

#!/usr/bin/python3
import queue
import threading
import time
exitFlag = 0
class myThread (threading.Thread):
    def __init__(self, threadID, name, q):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.q = q
    def run(self):
        print ("开启线程:" + self.name)
        process_data(self.name, self.q)
        print ("退出线程:" + self.name)
"""
以上都是一样的
"""
def process_data(threadName, q):
    while not exitFlag:
        queueLock.acquire()
        if not workQueue.empty():
            data = q.get()     #这里在模拟任务
            queueLock.release()
            print ("%s processing %s" % (threadName, data))
        else:
            queueLock.release()
        time.sleep(1)
threadList = ["Thread-1", "Thread-2", "Thread-3"]
nameList = ["One", "Two", "Three", "Four", "Five"]
queueLock = threading.Lock()
workQueue = queue.Queue(10)
threads = []
threadID = 1
# 创建新线程,不需要单独去定义什么 tName!!!!!! 这里通过循环 + 列表(各个参数的)构造
for tName in threadList:
    thread = myThread(threadID, tName, workQueue)
    thread.start()
    threads.append(thread)
    threadID += 1
# 填充队列
queueLock.acquire()
for word in nameList:
    workQueue.put(word)#将这些进程都填到队列里
queueLock.release()
# 等待队列清空,这个循环在队列空之前会一直反复 pass,程序卡在此处
while not workQueue.empty():
    pass
# 通知线程是时候退出
exitFlag = 1
# 等待所有线程完成
for t in threads:
    t.join()
print ("退出主线程")

1752585186421

# re

r=re.match(pattern,string,flags=0)
#从起始位置匹配,起始不匹配直接 none,但是后面可以接两个参数来改变起始范围
pattren:正则表达式,也可以只是个普通的待查找部分
string:要匹配的字符串
flags:标志位,是否匹配大小写之类

返回的是一个满足要求的对象,可以再使用其他方法:

r.group(0/无参)   #返回所有用正则匹配部分
r.group(1)       #返回第一个用正则匹配的部分
r.group(1,2)     #返回的是元组
r.groups()       #返回所有正则匹配的部分,但是以元组形式
r.start(0/无参)   #返回起始索引,类似有 end
r.span()         #返回 start 和 end

r=re.search(pattern, string, flags=0)
#在整个字符串中找第一个匹配的部分,其他同上

r=re.sub(pattern, repl, string, count=0, flags=0)
repl:替换的字符串,也可以是函数(这个函数必须返回字符串,str()很可能用到)
count:替换最大次数,默认的0就是全部替换
>>>import re
>>> pattern = re.compile(r'([a-z]+) ([a-z]+)', re.I)   # re.I 表示忽略大小写
>>> m = pattern.match('Hello World Wide Web')
>>> print m                               # 匹配成功,返回一个 Match 对象
<_sre.SRE_Match object at 0x10bea83e8>
>>> m.group(0)                            # 返回匹配成功的整个子串
'Hello World'
>>> m.span(0)                             # 返回匹配成功的整个子串的索引
(0, 11)
>>> m.group(1)                            # 返回第一个分组匹配成功的子串
'Hello'
>>> m.span(1)                             # 返回第一个分组匹配成功的子串的索引
(0, 5)
>>> m.group(2)                            # 返回第二个分组匹配成功的子串
'World'
>>> m.span(2)                             # 返回第二个分组匹配成功的子串
(6, 11)
>>> m.groups()                            # 等价于 (m.group (1), m.group (2), ...)
('Hello', 'World')
>>> m.group(3)                            # 不存在第三个分组
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: no such group

r=re.compile(pattern[, flags])
flags:可选

1752737540181

r=findall(string[, pos[, endpos]])
#全部查找,返回的是列表,如果多个匹配式子,则返回元组列表。
类似的有
r=re.finditer(pattern, string, flags=0)
但是返回的是迭代器,可以用于循环

1752738001449

伟大!无需多言!
re.split(pattern, string[, maxsplit=0, flags=0])

注意:以上返回的基本都是对象!!!

1752738165595

正则表达式本身是一种特殊语法的字符串:

Python 正则表达式 | 菜鸟教程 ,一般要用 r'xxx',防止 python 自己转义

# Python

# 基本操作

# 标识符

_foo

该函数不能直接访问类属性,需要类提供接口,并且不能使用 form xxx import * 导入

__foo

类的私有成员

__foo__

python 中的特殊方法,如 __init__ 是类的构造函数(析构函数是 __del__

' 单引号

" 双引号

''' 或者 """ 三引号

都用作表示字符串,开始结束必须相同。

三引号可以跨行,可以作为多行注释(当然不是说它是注释符,它的作用是可以实现其中内容的所见即所得,类似于 <pre> 标签的作用)

#

注释

# 标准数据类型

# 数字

与 C++ 不同,Python 的引用可以手动删除

del var_a,var_b;

数字类型有四种:int,long,float,complex (复数)

可以使用 ** 幂运算

# 字符串

可以从右向左索引,但是最后一个是 - 1

所以假设一共 6 个字符,第一个字符索引是 0 或者 - 6,最后一个是 5 或者 - 1

可以截取

s='abcdef'
s[1:5]
#按照下标,注意区间是左闭右开,如果是截到最后一个,第二个参数放空,即 s [1:]

可以 "运算"

str=u'sss'    #定义使用 unicode 的字符串
str=str+str   #+:字符串连接符
str=str*2     #*:重复操作
# 内建函数

比如:
1752564828242

#上图的那个是默认值
str="你是?"
bytes=str.encode("GBK")
bytes.decode()   #默认是 UTF-8,所以这里应该改为 bytes.decode ("GBK"),与上面保持一致

1752565242279

17525652641041752565284134

1752565330706

1752565405839

# 列表

t=['a','b','c']
#索引和运算类似字符串

# 元组

t=('a','b','c')
#相当于只读列表

# 字典

t={'a':'aa','b':'bb','c':'cc'}
#存储的是键值对,一个键的值是唯一的,先后定义其值取后,键不可变,所以不能是列表,但可以是元组 / 字符串
print t['a']   #输出 aa
print t        #完整输出字典
print t.keys   #输出所有键
print t.values #输出所有值
del t['a']     #删除该条目
t.clear()      #清空
del t          #删除字典,直接变成 not defined
# 内置函数 / 方法

函数

cmp()     #比较俩个字典
len()     #计算元素个数,即多少个键
str()     #见前
type()    #返回变量类型

方法

1752566073796

# 数据类型转换

1752562120293

其中 str () 和 repr () 作用类似,都可以将对象等转换为字符串但是 repr () 生成的可以被用来重新生成对象,就像是将对象序列化了一样:

1752562894064

# 运算符

# 成员运算符

in

在指定序列中查找值,找到返回 true,反之 false

not in

类上

# 身份运算符

is

is not

比较两者的存储单元是否相同,也就是否是同一个对象的引用

相当于 id (xxx)==id (xxx), 和 id (xxx)!=id (xxx)

//id () 用于获取对象内存地址

三目运算符

age=20
message="成年人" if age>=18 else "未成年人"
#这样可以不用写那么多判断语句,可以直接夹在赋值语句里

# 输入输出

print 默认输出后换行,如果不换要在变量结尾加 ,

::input 输入的数据默认都是 str

# 字符串

print r'sssss'   #输出原始字符串,此时不会转义特殊字符(此时就可以写 ' 而不是 \')。r 可以大写。

1752564269362

# 格式化

print "this is %s and %d" % ("我去"1)
#类似 C 的 printf

# 条件

if 1==1:
    print 1
elif (2==2 and 2==2) or (2==2 or 2 if 2=2 else 1) :
    print 2
else:
    print 0

# 循环

# for

rang (), 用于生成数值序列,不过计数是从 0 开始。所以:

for i in rang(5):
	print(i)
#输出是 0 到 4

# while

continue:跳过当前迭代,直接进入下一次(如有),在这之后的不会执行,所以会和 i 一起用

for i in range(5):
	if i == 3:
	continue
	print(i)
#输出没有 3

break:直接跳出 while 循环

//for 和 while 都可以跟 else 连用,正常终止时执行,被打断时一起被跳过

五。函数

def 函数名 (参数):

​ 函数体

#如果要返回值,则使用 return

// 空函数写 pass(pass 是占位语句,本身没有含义,也不影响运行)

默认参数与可选参数:

def sum_numbers(*args):#这里的 * 表示任意数量的非关键字参数,若为 ** 则表示任意数量的关键字参数
	return sum(args)
result = sum_numbers(1, 2, 3, 4)
print(result) # 输出: 10

非关键字参数的值不会赋值给该关键字

# 类、函数

// 用于封装数据(属性)和操作方法(函数),调用时可提供特定功能。

//python 中有内置的类

#Python 中一切都是对象,对象是类的实例,连 int 和 float 都是类

class Dog:
    '类的帮助信息'
    count='1';
	def __init__(self): # 构造函数
		self.Race = 'dog'
	def call(self): 	# 方法
		print('wang')
#self 代表类的实例,调用时不必传入
#不像 C++,python 中的成员变量只要在函数中出现就是定义,而在外面定义的那个(count)是类似于 C++ 中的静态成员变量,属于类而不是对象,可以直接使用 Dog.count 访问
t=Dog()     #实例化对象
t.age=1   #添加类属性,是这样的
del t.age #删除类属性

# 内置类函数 / 属性

函数

hasattr(emp1, 'age')    # 如果存在 'age' 属性返回 True。
getattr(emp1, 'age')    # 返回 'age' 属性的值
setattr(emp1, 'age', 8) # 添加属性 'age' 值为 8
delattr(emp1, 'age')    # 删除属性 'age'

属性

__dict__ : 类的属性(包含一个字典,由类的数据属性组成)
__doc__ :类的文档字符串
__name__: 类名
__module__: 类定义所在的模块(类的全名是'__main__.className',如果类位于一个导入模块mymod中,那么className.__module__ 等于 mymod)   #...... 怎么说?感觉可以用来。。。。。。
__bases__ : 类的所有父类构成元素(包含了一个由所有父类组成的元组)

# 继承

class Pet:
    #...
class Dog(Pet):   
	#... 可以多重继承,可以重写,可以重载(使用 def __add__(self,other) 重载 +)

权限:

class a: 
	__aaa=1          #私有变量
	def __aa(self): 
        pass
    #私有函数,内部使用时:self.__aa ()

与 C++ 不一样,类外可以访问私有数据,但是需要通过类来:

t=a()
t._a__aaa
#这里附带一句,在类中,_foo 指的是保护类型

# 内置类函数

1752568078240

# 杂项

# 按位运算

& #按位与 3 & 2 = 2 (全为 1 时为 1)

| #按位或 3 | 2 = 3 (其中一个是 1 时取 1)

^ #按位异或 3 ^ 2 = 1 (1 和 0 时为 1)
     #按位取反       ~3  = −4            (就是反过来而已)

<< #向左移位 3 << 1 = 6

>> #向右移位 3 >> 1 = 1

:: 在二进制中移位,空位全部补 0

# 其他

python3 之前默认使用 ascll 编码,如要使用中文需在文件头加上

# coding=utf-8 或者  # -*- coding: UTF-8

在存储时也要设置为 utf-8 格式

最好以 #!/user/bin/python 开头

为了让 python2 兼容 python3 的语法,请导入__future__包

python 允许一行多条语句,但需要用 ; 隔开

python 的保留字都是纯小写字母

缩进没有一定多少个空格,但是同一个缩进层次的必须对齐,一般使用单个制表符或两 / 四个空格。

可以使用 \ 来将一句分多行显示,在括号中的不用