范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

python常见面试问题整理

  1、python装饰器
  定义:在不改变原函数的代码和调用方式的情况下,实现对函数的功能的增强。
  (1) 一般装饰器写法 def timer(func):     def decorator(*args, **kwargs):         start = time.time()         func(*args, **kwargs)         end = time.time()         print(f"执行用时:{end - start}s")     return decorator   @timer def want_sleep(sleep_time):     time.sleep(sleep_time)       want_sleep(10) #输出如下 执行用时:10.0073800086975098s
  (2)带参数的装饰器 def say_hello(contry):     def wrapper(func):         def deco(*args, **kwargs):             if contry == "china":                 print("你好!")             elif contry == "america":                 print("hello.")             else:                 return             # 真正执行函数的地方             func(*args, **kwargs)         return deco     return wrapper  # 小明,中国人 @say_hello("china") def xiaoming():     pass  # jack,美国人 @say_hello("america") def jack():     pass
  (3) 不带参数的类装饰器
  基于类装饰器的实现,必须实现 __call__  和 __init__ 两个内置函数。 __init__  :接收被装饰函数 __call__  :实现装饰逻辑。 class logger(object):     def __init__(self, func):         self.func = func      def __call__(self, *args, **kwargs):         print("[INFO]: the function {func}() is running..."             .format(func=self.func.__name__))         return self.func(*args, **kwargs)  @logger def say(something):     print("say {}!".format(something))  say("hello") #执行一下,看看输出 [INFO]: the function say() is running... say hello!
  (4) 带参数的类装饰器
  上面不带参数的例子,你发现没有,只能打印INFO 级别的日志,正常情况下,我们还需要打印DEBUG  WARNING 等级别的日志。 这就需要给类装饰器传入参数,给这个函数指定级别了。
  带参数和不带参数的类装饰器有很大的不同。
  __init__  :不再接收被装饰函数,而是接收传入参数。 __call__  :接收被装饰函数,实现装饰逻辑。 class logger(object):     def __init__(self, level="INFO"):         self.level = level      def __call__(self, func): # 接受函数         def wrapper(*args, **kwargs):             print("[{level}]: the function {func}() is running..."                 .format(level=self.level, func=func.__name__))             func(*args, **kwargs)         return wrapper  #返回函数  @logger(level="WARNING") def say(something):     print("say {}!".format(something))  say("hello")  执行结果如下: [WARNING]: the function say() is running... say hello!
  (5). 使用偏函数与类实现装饰器
  绝大多数装饰器都是基于函数和闭包实现的,但这并非制造装饰器的唯一方式。
  事实上,Python 对某个对象是否能通过装饰器( @decorator )形式使用只有一个要求: decorator 必须是一个"可被调用(callable)的对象 。
  对于这个 callable 对象,我们最熟悉的就是函数了。
  除函数之外,类也可以是 callable 对象,只要实现了__call__  函数(上面几个例子已经接触过了)。
  还有容易被人忽略的偏函数其实也是 callable 对象。
  接下来就来说说,如何使用 类和偏函数结合实现一个与众不同的装饰器。
  如下所示,DelayFunc 是一个实现了 __call__  的类,delay 返回一个偏函数,在这里 delay 就可以做为一个装饰器。(以下代码摘自 Python工匠:使用装饰器的小技巧) import time import functools  class DelayFunc:     def __init__(self,  duration, func):         self.duration = duration         self.func = func      def __call__(self, *args, **kwargs):         print(f"Wait for {self.duration} seconds...")         time.sleep(self.duration)         return self.func(*args, **kwargs)      def eager_call(self, *args, **kwargs):         print("Call without delay")         return self.func(*args, **kwargs)  def delay(duration):     """     装饰器:推迟某个函数的执行。     同时提供 .eager_call 方法立即执行     """     # 此处为了避免定义额外函数,     # 直接使用 functools.partial 帮助构造 DelayFunc 实例     return functools.partial(DelayFunc, duration)
  我们的业务函数很简单,就是相加 @delay(duration=2) def add(a, b):     return a+b
  来看一下执行过程 >>> add    # 可见 add 变成了 Delay 的实例 <__main__.DelayFunc object at 0x107bd0be0> >>>  >>> add(3,5)  # 直接调用实例,进入 __call__ Wait for 2 seconds... 8 >>>  >>> add.func # 实现实例方法 
  (6) 如何写能装饰类的装饰器?
  用 Python 写单例模式的时候,常用的有三种写法。其中一种,是用装饰器来实现的。
  以下便是我自己写的装饰器版的单例写法。 instances = {}  def singleton(cls):     def get_instance(*args, **kw):         cls_name = cls.__name__         print("===== 1 ====")         if not cls_name in instances:             print("===== 2 ====")             instance = cls(*args, **kw)             instances[cls_name] = instance         return instances[cls_name]     return get_instance  @singleton class User:     _instance = None      def __init__(self, name):         print("===== 3 ====")         self.name = name
  可以看到我们用singleton 这个装饰函数来装饰 User 这个类。装饰器用在类上,并不是很常见,但只要熟悉装饰器的实现过程,就不难以实现对类的装饰。在上面这个例子中,装饰器就只是实现对类实例的生成的控制而已。
  其实例化的过程,你可以参考我这里的调试过程,加以理解。
  (7)wraps 装饰器有啥用?
  在 functools 标准库中有提供一个 wraps 装饰器,你应该也经常见过,那他有啥用呢?
  先来看一个例子 def wrapper(func):     def inner_function():         pass     return inner_function  @wrapper def wrapped():     pass  print(wrapped.__name__) #inner_function
  为什么会这样子?不是应该返回 func  吗?
  这也不难理解,因为上边执行func  和下边 decorator(func)  是等价的,所以上面 func.__name__  是等价于下面decorator(func).__name__  的,那当然名字是 inner_function  def wrapper(func):     def inner_function():         pass     return inner_function  def wrapped():     pass  print(wrapper(wrapped).__name__) #inner_function
  那如何避免这种情况的产生?方法是使用 functools .wraps 装饰器,它的作用就是将  被修饰的函数(wrapped)  的一些属性值赋值给  修饰器函数(wrapper)  ,最终让属性的显示更符合我们的直觉。 from functools import wraps  def wrapper(func):     @wraps(func)     def inner_function():         pass     return inner_function  @wrapper def wrapped():     pass  print(wrapped.__name__) # wrapped
  准确点说,wraps 其实是一个偏函数对象(partial),源码如下 def wraps(wrapped,           assigned = WRAPPER_ASSIGNMENTS,           updated = WRAPPER_UPDATES):     return partial(update_wrapper, wrapped=wrapped,                    assigned=assigned, updated=updated)
  可以看到wraps其实就是调用了一个函数update_wrapper ,知道原理后,我们改写上面的代码,在不使用 wraps的情况下,也可以让 wrapped.__name__  打印出 wrapped,代码如下: from functools import update_wrapper  WRAPPER_ASSIGNMENTS = ("__module__", "__name__", "__qualname__", "__doc__",                        "__annotations__")  def wrapper(func):     def inner_function():         pass      update_wrapper(inner_function, func, assigned=WRAPPER_ASSIGNMENTS)     return inner_function  @wrapper def wrapped():     pass  print(wrapped.__name__)2、列表和元组的区别列表属于可变序列,它的元素可以随时修改或删除,元组是不可变序列,其中元素不可修改,只能整体替换。 列表可以使用append()、extend()、insert()、remove()和pop()等方法实现添加和修改,元组则没有这几个方法。 列表可以使用切片访问和修改列表中的元素,元组也支持切片,但是它只能通过切片访问。 元组比列表的访问和处理速度快,如果只需要访问不需要修改,建议使用元组。 列表不能作为字典的键,而元组则可以。 3、多进程与多线程
  3.1 线程与进程的区别
  操作系统创建进程,要给进程分配资源,进程是操作系统分配资源的基本单位。
  操作系统创建的线程,要是在CPU上调度执行,线程是操作调度执行的基本单位。
  进程包含线程,一个进程离可以有一个线程,也可以有多个线程。
  3.2 python多线程
  (1)普通方式创建线程 from random import randint from threading import Thread from time import time,sleep   def download(filename):     print("开始下载{}...".format(filename))     time_to_download=randint(5,10)     sleep(time_to_download)     print("%s下载完成!耗时%.2f秒." % (filename,time_to_download))  def main():     start=time()     t1=Thread(target=download,args=("Python从入门到放弃",))     t1.start()     t2=Thread(target=download,args=("三国义演.txt",))     t2.start()     t1.join()     t2.join()     end=time()     print("总共耗费了%.3f秒" % (end-start))  if __name__=="__main__":     main()      #output     开始下载Python从入门到放弃... 开始下载三国义演.txt... 三国义演.txt下载完成!耗时10.00秒. Python从入门到放弃下载完成!耗时10.00秒. 总共耗费了10.008秒
  (2)继承方式创建线程 from random import randint from threading import Thread from time import time, sleep   class DownloadTask(Thread):      def __init__(self, filename):         super(DownloadTask,self).__init__()         self._filename = filename      def run(self):         print("开始下载%s..." % self._filename)         time_to_download = randint(5, 10)         sleep(time_to_download)         print("%s下载完成! 耗费了%d秒" % (self._filename, time_to_download))   def main():     start = time()     t1 = DownloadTask("Python从入门到住院.pdf")     t1.start()     t2 = DownloadTask("Peking Hot.avi")     t2.start()     t1.join()     t2.join()     end = time()     print("总共耗费了%.2f秒." % (end - start))   if __name__ == "__main__":     main()      #output 开始下载Python从入门到住院.pdf... 开始下载Peking Hot.avi... Python从入门到住院.pdf下载完成! 耗费了6秒 Peking Hot.avi下载完成! 耗费了9秒 总共耗费了9.01秒.
  3.2 python多进程 from multiprocessing import Process from os import getpid from random import randint from time import time, sleep   def download_task(filename):     print("启动下载进程[%d],开始下载%s..." % (getpid() ,filename))     time_to_download = randint(5, 10)     sleep(time_to_download)     print("%s下载完成! 耗费了%d秒" % (filename, time_to_download))   def main():     print("Parent process %s." % (getpid()))     start = time()     p1 = Process(target=download_task, args=("Python从入门到住院.pdf", ))     p2 = Process(target=download_task, args=("Peking Hot.avi", ))     p1.start()     p2.start()     p1.join()     p2.join()     end = time()     print("总共耗费了%.2f秒." % (end - start))   if __name__ == "__main__":     main()    #output 启动下载进程[14156],开始下载Peking Hot.avi... 启动下载进程[1232],开始下载Python从入门到住院.pdf... Peking Hot.avi下载完成! 耗费了5秒 Python从入门到住院.pdf下载完成! 耗费了10秒 总共耗费了10.26秒. 4、re模块---正则表达式
  一、什么是正则表达式
  正则表达式(Regular expression)是一组由字母和符号组成的特殊文本, 它可以用来从文本中找出满足你想要的格式的句子。
  比如我们在网站中看到对用户名规则做出了如下限制:只能包含小写字母、数字、下划线和连字符,并且限制用户名长度在3~15个字符之间,如何验证一个用户名是否符合规则呢 ?我们使用以下正则表达式:
  以上的正则表达式可以接受john_doe、jo-hn_doe、john12_as,但不能匹配A1,因为它包含了大写字母而且长度不到3个字符
  1.1 re.compile
  compile:re.compile是将正则表达式转换为模式对象,这样可以更有效率匹配。使用compile转换一次之后,以后每次使用模式时就不用进行转换 pattern:写正则表达式 flags:匹配模式
  从compile()函数的定义中,可以看出返回的是一个匹配对象,它单独使用就没有任何意义,需要和findall(), search(), match()搭配使用。 compile()与findall()一起使用,返回一个列表。 # compile配合findall import re a = "0355-67796666" b = re.compile(r"d+-d{8}") r = re.findall(b,a) print(r)   import re a = "0355-67796666" b = re.compile(r"d+-d{8}") r = b.findall(a) print(r)   # 直接使用findall import re a = "0355-67796666" r = re.findall(r"d+-d{8}",a) print(r)   # compile配合search import re a = "0355-67796666" 正则 = re.compile(r"d+-d{8}") r = re.search(正则,a) print(r.group())   # compile配合match import re a = "0355-67796666" 正则 = re.compile(r"d+-d{8}") r = re.match(正则,a) print(r.group())
  1.2 re.match
  match 从字符串的第一个字符开始匹配,如果未匹配到返回None,匹配到则返回一个对象
  match判断正则表达式是否从开始处(首字母)匹配一个字符串,例如第一个不是d(数字),返回None import re a = "A83C72D1D8E67" r = re.match("d",a) print(r) # 返回对象所在位置 print(r.group()) # 返回找到的结果,例如8 print(r.span()) # 返回一个元组表示匹配位置(开始,结束)
  1.3 re.search
  Search与match有些类似,只是搜索整个字符串然后第一个匹配到指定的字符则返回值,未匹配到则返回None。获取值得方法也需要通过group() 从字符串开始往后匹配,一匹配到则返回一个对象。需要通过group来获取匹配到的值。
  search 遍历字符串,找到正则表达式匹配的第一个位置 import re a = "A83C72D1D8E67" r = re.search("d",a) print(r) print(r.group())
  1.4 re.findall
  Findall是匹配出字符串中所有跟指定值有关的值,并且以列表的形式返回。未匹配到则返回一个空的列表。匹配出指定字符的所有值,并以列表返回值。
  二、简单的模式:字符匹配
  元字符
  描述
  .
  句号匹配任意单个字符除了换行符
  []
  字符种类,匹配方括号内的任意字符,*  **中括号内每个字符是或**  *(or)*  *  的关系
  [^]
  否定的字符种类,匹配除了方括号里的任意字符
  *
  匹配*  **0**  *次或无限次,重复在*号之前的字符
  +
  匹配* **1** *次或无限次,重复在* **+** *号之前的字符
  ?
  匹配*  **0**  *次或*  **1**  *次,重复在*  **?**  *号之前的字符
  {n,m}
  匹配num个大括号之前的字符(n<=num<=m)
  (xyz)
  字符集又称做*  **组**  *,匹配与xyz完全相等的字符串,*  **每个字符是且**  *(and)*  *  的关系
  |
  或运算符,匹配符号前或后的字符
  **
  转义字符,用于匹配一些保留字符 [ ]、( )、{ }、. 、 * 、+ 、? 、^ 、$、 、|
  ^
  从字符串开始位置开始匹配
  $
  从字符串末端开始匹配
  反斜杠后面跟普通字符实现特殊功能
  特殊字符
  描述
  d
  匹配数字,相当于[0-9]
  D
  不匹配数字,相当于[*  **^**  *0-9]
  s
  匹配空白字符(包括空格、换行符、制表符等),相当于 [	 rfv]
  S
  与s相反,相当于 [	 rfv]
  w
  匹配中文,下划线,数字,英文,相当于[a-zA-z0-9_]
  W
  与w相反,匹配特殊字符,如$、&、空格、 、	等
  b
  匹配单词的开始或结束
  B
  与b相反
  2.1 元字符 # 提取字符串a中所有的数字,返回结果:["7", "6", "3", "6"] import re a = "孙悟空7猪八戒6沙和尚3唐僧6白龙马" r = re.findall("[0-9]",a) print(r)   # 提取字符串a中所有非数字,返回:["孙", "悟", "空", "猪", "八", "戒", "沙", "和", "尚", "唐", "僧", "白", "龙", "马"] import re a = "孙悟空7猪八戒6沙和尚3唐僧6白龙马" r = re.findall("[^0-9]",a) print(r)   # 找到字符串中间字母是d或e的单词,返回:["xdz", "xez"] import re a = "xyz,xcz,xfz,xdz,xaz,xez" r = re.findall("x[de]z",a) print(r)   # 找到字符串中间字母不是d或e的单词,返回:["xyz", "xcz", "xfz", "xaz"] import re a = "xyz,xcz,xfz,xdz,xaz,xez" r = re.findall("x[^de]z",a) print(r)   # 找到字符串中间字母是d或e或f的单词,返回:["xfz", "xdz", "xez"] import re a = "xyz,xcz,xfz,xdz,xaz,xez" r = re.findall("x[d-f]z",a) print(r)
  2.2 概括字符集 # 提取字符串a中所有的数字 import re a = "Excel 12345Word 23456_PPT12lr" r = re.findall("d",a) print(r) # 提取字符串a中所有非数字 import re a = "Excel 12345Word 23456_PPT12lr" r = re.findall("D",a) print(r)   # w 可以提取中文,英文,数字和下划线,不能提取特殊字符 import re a = "Excel 12345Word 23456_PPT12lr" r = re.findall("w",a) print(r)   # W 提取特殊字符、空格、 、	等 import re a = "Excel 12345Word 23456_PPT12lr" r = re.findall("W",a) print(r)
  2.3 数量词 # 提取大小写字母混合的单词 import re a = "Excel 12345Word23456PPT12Lr" r = re.findall("[a-zA-Z]{3,5}",a) print(r) # 贪婪与非贪婪 【Python默认使用贪婪模式】 贪婪:"[a-zA-Z]{3,5}" # 先找三个连续的字母,最多找到5个连续的字母后停止。在3个以后且5个以内发现了不是子母的也停止。 非贪婪:"[a-zA-Z]{3,5}?"或"[a-zA-Z]{3}" 建议使用后者,不要使用?号,否则你会与下面的?号混淆 # 匹配0次或无限多次*号,*号前面的字符出现0次或无限次 import re a = "exce0excell3excel3" r = re.findall("excel*",a) print(r)   # 匹配1次或者无限多次+号,+号前面的字符至少出现1次 import re a = "exce0excell3excel3" r = re.findall("excel+",a) print(r) # 匹配0次或1次 ?号,?号经常用来去重复 import re a = "exce0excell3excel3" r = re.findall("excel?",a) print(r)
  2.4 边界匹配^和$
  # 限制电话号码的位置必需是8-11位才能提取 import re tel = "13811115888" r = re.findall("^d{8,11}#39;,tel) print(r)
  2.5 ^组( ) # 将abc打成一个组,{2}指的是重复几次,匹配abcabc import re a = "abcabcabcxyzabcabcxyzabc" r = re.findall("(abc){2}",a) print(r)
  可以加入很多个组
  2.6 匹配模式参数 # findall第三参数re.I忽略大小写 import re a = "abcFBIabcCIAabc" r = re.findall("fbi",a,re.I) print(r) # 多个模式之间用| 连接在一起 import re a = "abcFBI abcCIAabc" r = re.findall("fbi.{1}",a,re.I | re.S) # 匹配fbi然后匹配任意一个字符包括  print(r)
  注:.句号,不匹配 ,但是使用re.S之后,匹配所有字符包括换行符 1).re.I(re.IGNORECASE): 忽略大小写 2).re.M(MULTILINE): 多行模式,改变’^’和’$’的行为 3).re.S(DOTALL): 点任意匹配模式,改变’.’的行为 4).re.L(LOCALE): 使预定字符类 w W b B s S 取决于当前区域设定 5).re.U(UNICODE): 使预定字符类 w W b B s S d D 取决于unicode定义的字符属性 6).re.X(VERBOSE): 详细模式。这个模式下正则表达式可以是多行,忽略空白字符,并可以加入注释
  2.7 re.sub替换字符串 # 把FBI替换成BBQ import re a = "abcFBIabcCIAabc" r = re.sub("FBI","BBQ",a) print(r) # 把FBI替换成BBQ,第4参数写1,证明只替换第一次,默认是0(无限替换) import re a = "abcFBIabcFBIaFBICIAabc" r = re.sub("FBI","BBQ",a,1) print(r) 注意:虽然字符串的内置方法 字符串.replace 也可以进行替换,但是正则表达式更强大 # 拓展知识 import re a = "abcFBIabcFBIaFBICIAabc" def 函数名(形参): pass r = re.sub("FBI",函数名,a,1) print(r)
  分析:如果找到了FBI这个子串,会将FBI当成参数传到形参中,pass是什么都没返回,所以FBI被空字符串代替了。 # 把函数当参数传到sub的列表里,实现把业务交给函数去处理,例如将FBI替换成$FBI$ import re a = "abcFBIabcFBIaFBICIAabc" def 函数名(形参): 	分段获取 = 形参.group() # group()在正则表达式中用于获取分段截获的字符串,获取到FBI 	return "#39; + 分段获取 + "#39; r = re.sub("FBI",函数名,a) print(r)
  2.8 把函数做为参数传递 # 将字符串中大于等于5的替换成9,小于5的替换成0 import re a = "C52730A52730D52730" def 函数名(形参):     分段获取 = 形参.group()     ifint(分段获取) >= 5:     	return"9" else: 	return "0" r = re.sub("d",函数名,a) print(r)
  2.9 group分组 import re a = "123abc456" print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(0) #123abc456,返回整体 print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(1) #123 print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(2) #abc print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(3) #456正则表达式中的三组括号把匹配结果分成三组 group() 同group(0)就是匹配正则表达式整体结果 group(1) 列出第一个括号匹配部分,group(2) 列出第二个括号匹配部分,group(3) 列出第三个括号匹配部分。 没有匹配成功的,re.search()返回None 当然正则表达式中没有括号,group(1)肯定不对了。 import re a = "life is short,i use python" r = re.search("life(.*)python",a) print(r.group(1))  等同于 import re a = "lifeis short,i use python" r = re.findall("life(.*)python",a) print(r)# 拓展知识 import re a = "life is short,i use python,i love python" r = re.search("life(.*)python(.*)python",a) print(r.group(0)) # 完整正则匹配 print(r.group(1)) # 第1个分组之间的取值 print(r.group(2)) # 第2个分组之间的取值 print(r.group(0,1,2))# 以元组形式返回3个结果取值 print(r.groups()) # 返回就是group(1)和group(2)
  三、正则表达式的一些建议
  1、常用的正则表达式,不用自己写,在百度上搜索常用正则表达式,不要重复造轮子 2、如果内置方法可以快速解决问题,建议不要化简为繁
  附1:正则表达式基础语法
  d
  指出一个字符串的开始
  $
  指出一个字符串的结束
  将下一个字符标记为一个特殊字符、或一个原义字符、或一个向后引用、或一个八进制转义符
  ^abc
  匹配所有以 "abc" 开始的字符串 (例如:"abc","abccba")
  abc$
  匹配所有以"abc" 结尾的字符串 (例如:"gggabc","reddcba")
  ^abc$
  匹配开始和结尾都为"abc"的字符串 (例如:"abc")
  abc
  没有任何字符,匹配任何包含"abc"的字符串 (例如:"aaaabccc","abc123")
  n
  匹配n " ":匹配换行符 "/"这里是 he / 连在一起写,匹配 " / " 字符
  *
  匹配前面的子表达式零次或多次
  +
  匹配前面的子表达式一次或多次
  ?
  匹配前面的子表达式零次或一次
  ac*
  匹配字符串其中一个a后面跟着零个或若干个c (例如:"accc","abbb")
  ac+
  匹配字符串其中一个a后面跟着至少一个c或者多个 (例如:"ac","acccccccc")
  ac?
  匹配字符串其中一个a后面跟着零个或者一个c (例如:"a","ac")
  a?c+$
  匹配字符串的末尾有零个或一个a跟着一个或多个c (例如:"ac","acccccc",""c"","ccccccc")
  {n}
  n为非负整数,匹配n次
  {n,}
  n为非负整数,匹配至少n次
  {n,m}
  n,m为非负整数,最少匹配n次 最多匹配m次
  ab{3}
  表示一个字符串有一个a后面跟随2个b (例如:"abb","abbbbb")
  ab{3,}
  表示一个字符串有一个a后面跟随至少2个b (例如:"abb","abbb")
  ab{3,6}
  表示一个字符串有一个a后面跟随3到6个b (例如:"abbb","abbbb","abbbb")
  |
  表示"或"
  .
  表示任何字符
  a|b
  表示一个字符串里有 a 或者 b (例如:"a","b","ab","abc")
  a.
  表示一个字符串有一个 a 后面跟着一个任意字符 (例如:"a1","a456","avv")
  附2:方括号里用"^"表示不希望出现的字符
  [abc]
  表示字符集合,表示一个字符串有一个"a"或"b"或"c" 等价于 [z|b|c]
  [^abc]
  表示一个字符串中不应该出现abc,即是匹配未包含改集合的任意字符
  [a-z]
  表示一个字符串中存在一个a和z之间的所有字母
  [0-9]
  表示一个字符串中存在一个0和9之间的所有数字
  [^a-z]
  表示一个字符串中不应该出现a到z之间的任意一个字母
  [1]
  表示一个字符串中以字母开头
  [0-9]%
  表示一个百分号前有一个的数字;
  附3:由字符""和另一个字符组成特殊含义
  匹配一个数字字符,等价[0-9]
  d
  匹配一个非数字字符,等价 0-9
  D
  匹配一个换页符,等价和cL
  f
  匹配一个换行符。等价于 和cJ
  匹配一个回车符。等价于 和cM
  r
  匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ f r	v]
  s
  匹配任何非空白字符。等价于   f r	v
  S  5、requests库
  实例 # 导入 requests 包 import requests  # 发送请求 x = requests.get("https://www.runoob.com/")  # 返回网页内容 **print**(x.text)response响应属性或方法
  属性或方法
  说明
  apparent_encoding
  编码方式
  close()
  关闭与服务器的连接
  content
  返回响应的内容,以字节为单位
  cookies
  返回一个 CookieJar 对象,包含了从服务器发回的 cookie
  elapsed
  返回一个 timedelta 对象,包含了从发送请求到响应到达之间经过的时间量,可以用于测试响应速度。比如 r.elapsed.microseconds 表示响应到达需要多少微秒。
  encoding
  解码 r.text 的编码方式
  headers
  返回响应头,字典格式
  history
  返回包含请求历史的响应对象列表(url)
  is_permanent_redirect
  如果响应是永久重定向的 url,则返回 True,否则返回 False
  is_redirect
  如果响应被重定向,则返回 True,否则返回 False
  iter_content()
  迭代响应
  iter_lines()
  迭代响应的行
  json()
  返回结果的 JSON 对象 (结果需要以 JSON 格式编写的,否则会引发错误)
  links
  返回响应的解析头链接
  next
  返回重定向链中下一个请求的 PreparedRequest 对象
  ok
  检查 "status_code" 的值,如果小于400,则返回 True,如果不小于 400,则返回 False
  raise_for_status()
  如果发生错误,方法返回一个 HTTPError 对象
  reason
  响应状态的描述,比如 "Not Found" 或 "OK"
  request
  返回请求此响应的请求对象
  status_code
  返回 http 的状态码,比如 404 和 200(200 是 OK,404 是 Not Found)
  text
  返回响应的内容,unicode 类型数据
  url
  返回响应的 URL  # 导入 requests 包 import requests  # 发送请求 x = requests.get("https://www.runoob.com/")  # 返回 http 的状态码 print(x.status_code)  # 响应状态的描述 print(x.reason)  # 返回编码 print(x.apparent_encoding)
  输出结果如下: 200 OK utf-8
  实例 import requests  #发送请求 x = requests.get("https://www.runoob.com/try/ajax/json_demo.json")  # 返回 json 数据 print(x.json())  #输出:{"name": "网站", "num": 3, "sites": [{"name": "Google", "info": ["Android", "Google 搜索", "Google 翻译"]}, {"name": "Runoob", "info": ["菜鸟教程", "菜鸟工具", "菜鸟微信"]}, {"name": "Taobao", "info": ["淘宝", "网购"]}]}requests 方法
  requests 方法如下表:
  方法
  描述
  delete( url ,  args )
  发送 DELETE 请求到指定 url
  get(  url  ,   params, args  )
  发送 GET 请求到指定 url
  head( url ,  args )
  发送 HEAD 请求到指定 url
  patch(  url  ,   data, args  )
  发送 PATCH 请求到指定 url
  post( url ,  data, json, args )
  发送 POST 请求到指定 url
  put(  url  ,   data, args  )
  发送 PUT 请求到指定 url
  request( method ,  url ,  args )
  向指定的 url 发送指定的请求方法
  发送 get 请求: # 导入 requests 包 import requests  # 发送请求 x = requests.request("get", "https://www.runoob.com/")  # 返回网页内容 print(x.status_code) 输出结果如下: 200
  设置请求头: # 导入 requests 包 import requests    kw = {"s":"python 教程"}  # 设置请求头 headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}   # params 接收一个字典或者字符串的查询参数,字典类型自动转换为url编码,不需要urlencode() response = requests.get("https://www.runoob.com/", params = kw, headers = headers)  # 查看响应状态码 print (response.status_code)  # 查看响应头部字符编码 print (response.encoding)  # 查看完整url地址 print (response.url)  # 查看响应内容,response.text 返回的是Unicode格式的数据 print(response.text)
  输出结果如下: 200 UTF-8 https://www.runoob.com/?s=python+%E6%95%99%E7%A8%8B  ... 其他内容...
  post() 方法可以发送 POST 请求到指定 url,一般格式如下: requests.post(url, data={key: value}, json={key: value}, args)url  请求 url。 data  参数为要发送到指定 url 的字典、元组列表、字节或文件对象。 json  参数为要发送到指定 url 的 JSON 对象。 args  为其他参数,比如 cookies、headers、verify等。
  实例 # 导入 requests 包 import requests  # 发送请求 x = requests.post("https://www.runoob.com/try/ajax/demo_post.php")  # 返回网页内容 print(x.text)
  输出结果如下: 

本内容是使用 POST 方法请求的。

请求时间: 2022-05-26 17:30:47   post 请求带参数: # 导入 requests 包 import requests # 表单参数,参数名为 fname 和 lname myobj = {"fname": "RUNOOB","lname": "Boy"} # 发送请求 x = requests.post("https://www.runoob.com/try/ajax/demo_post2.php", data = myobj) # 返回网页内容 print(x.text)   输出结果如下:

你好,RUNOOB Boy,今天过得怎么样?6、常见的排序算法   选择排序O(n²) 从当前 元素后 的无序元素数组中找到最小值 如果找到了, 将该元素与当前元素交换 如果没找到, 说明当前元素是后续无序数组中的最小值 执行上述过程n-1 次 def selection_sort(array): # 最后一个元素无序比较, 所以执行n-1次 for i in range(len(array)-1): min_index = i # 从当前index+1的位置开始遍历 for j in range(i+1, len(array)): if array[j] < array[min_index]: min_index = j # 如果找到最小值 if i != min_index: array[i], array[min_index] = array[min_index], array[i]   冒泡排序O(n²) 本质就是将最大值移动到数组末端 比较cur和next, 如果cur > next, 则交换两者 执行上述过程n 次 def bubble_sort(array): for i in range(len(array)): # 每完成一次遍历, 结尾就有一个最大元素, 那么我们接下来的遍历过程可以-1 for j in range(len(array)-1-i): # array[j]表示cur if array[j] > array[j+1]: array[j], array[j+1] = array[j+1], array[j]   归并排序   归并排序适用于两个有序数组进行重新排序   合并两个有序数组 声明一个新数组, 该数组的长度 = 左数组 + 右数组 比较两个左数组和右数组的头元素, 小的值将添加到新数组的头部 重复步骤2, 直到某个数组没有元素为止 将剩余元素的数组直接添加到新数组末端 def merge(left, right): """ :param left: 左数组 :param right: 右数组 :return: """ # 因为我们是python的list, 所以不用考虑声明长度 result = [] while left and right: # 比较两个数组的头元素 if left[0] <= right[0]: # 通过list.pop删除并返回指定位置的元素 result.append(left.pop(0)) else: result.append(right.pop(0)) while left: result.append(left.pop(0)) while right: result.append(right.pop(0)) return result 对无序的数组进行重新排序 无序数组[a, b, c, d, e] 可以拆分成[a, b], [c, d, e] [a, b] 排序后得到[b, a] [c, d, e]可以拆分为[c, d], [e] [c, d] 排序后得到[d, c] 得到了三组有序数组 [d, c], [e] 归并后得到[d, c, e] [d, c, e], [b, a]归并后得到[d, b, c, a, e] def merge_sort(array): """ 使用递归实现分治思想 :param array: :return: """ # 一旦使用递归, 首先要考虑的是退出逻辑 if len(array) < 2: return array middle = len(array) // 2 left_array = array[:middle] right_array = array[middle:] return merge(merge_sort(left_array), merge_sort(right_array))   快速排序 从数组中选定一个基准(pivot) 遍历基础之后的元素, 将比它小的元素置于左边, 比它大的元素置于右边 声明i, j两个指针 比较pivot和j的值, 如果pivot > j, 交换i 和j 的值, i+1 不管比较的结果, j + 1 j到达末端, pivot和i-1 交换值 def partition(array, left, right): """ :param array: :param left: 左端索引 :param right: 右端索引 :return: """ # 为了方便我们理解, 这里选left pivot = left i = j = pivot + 1 while j <= right: if array[pivot] > array[j]: array[i], array[j] = array[j], array[i] i += 1 j += 1 array[i-1], array[pivot] = array[pivot], array[i-1] # 返回原pivot值的新索引 return i-1 7、迭代器与生成器   迭代器 迭代是Python最强大的功能之一,是访问集合元素的一种方式。 迭代器是一个可以记住遍历的位置的对象。 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。 迭代器有两个基本的方法: iter() 和 next() 。 字符串,列表或元组对象都可用于创建迭代器:   例子 >>> list=[1,2,3,4] >>> it = iter(list) # 创建迭代器对象 >>> print (next(it)) # 输出迭代器的下一个元素 1 >>> print (next(it)) 2 >>>import sys # 引入 sys 模块 list=[1,2,3,4] it = iter(list) # 创建迭代器对象 while True: try: print (next(it)) except StopIteration: sys.exit()   生成器   在 Python 中,使用了 yield 的函数被称为生成器(generator)。   跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。   在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。   调用一个生成器函数,返回的是一个迭代器对象。   以下实例使用 yield 实现斐波那契数列:   实例 #!/usr/bin/python3 import sys def fibonacci(n): # 生成器函数 - 斐波那契 a, b, counter = 0, 1, 0 while True: if (counter > n): return yield a a, b = b, a + b counter += 1 f = fibonacci(10) # f 是一个迭代器,由生成器返回生成 while True: try: print (next(f), end=" ") except StopIteration: sys.exit()   执行以上程序,输出结果如下: 0 1 1 2 3 5 8 13 21 34 558、类的继承   Python 同样支持类的继承,如果一种语言不支持继承,类就没有什么意义。派生类的定义如下所示:   class DerivedClassName(BaseClassName):   子类(派生类 DerivedClassName)会继承父类(基类 BaseClassName)的属性和方法。   BaseClassName(实例中的基类名)必须与派生类定义在一个作用域内。除了类,还可以用表达式,基类定义在另一个模块中时这一点非常有用: 9、lambda匿名函数   Python 使用 lambda 来创建匿名函数。   所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。 lambda 只是一个表达式,函数体比 def 简单很多。 lambda 的主体是一个表达式,而不是一个代码块。仅仅能在 lambda 表达式中封装有限的逻辑进去。 lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。 虽然 lambda 函数看起来只能写一行,却不等同于 C 或 C++ 的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。   语法   lambda 函数的语法只包含一个语句,如下: lambda [arg1 [,arg2,.....argn]]:expressionx = lambda a : a + 10 print(x(5)) # 输出15 sum_lambda = lambda a, b, c: a + b + c print(sum_lambda(1, 100, 10000)) #输出10101   lambda高阶函数示范 #匿名函数与max()函数配合使用 list1 = [{"a":10, "b":20},{"a":13,"b": 2},{"a":23,"b":13},{"a":32,"b":17}] m = max(list1,key=lambda x :x["a"]) print("列表最大数:",m)map() 映射函数 # 将列表中所有的值求平方后返回至列表 list1 =[1,3,5,7,9] it=map(lambda x:x**2,list1) for i in it: print(i,end=" ") #运行结果:1 9 25 49 81filter() 过滤函数 # 将列表中的偶数取出来 list2 = [1,2,5,6,8,9] it =filter(lambda x:x%2==0,list2) for i in it: print(i,end=" ") #运行结果:2 6 8reduce() 累计函数,常用于叠加或叠乘 # 求列表中所有数相乘的结果 list3 = [1,2,3,4,5,6] result = reduce(lambda x,y:x*y,list3) print(result) #运行结果为:720sorted()函数排序 1 ls = [{"a": 1, "b": 2, "c": 4}, {"a": 11, "b": 4, "c": 16}, {"a": 11, "b": 4, "c": 16}] 2 ls_sorted = sorted(ls, key=lambda d: d["b"], reverse=True) 3 print(ls_sorted) # [{"a": 11, "b": 4, "c": 16}, {"a": 11, "b": 4, "c": 16}, {"a": 1, "b": 2, "c": 4}]10、深拷贝与浅拷贝   深浅拷贝都是对源对象的复制,占用不同的内存空间   如果源对象只有一级目录的话,源做任何改动,不影响深浅拷贝对象   如果源对象不止一级目录的话,源做任何改动,都要影响浅拷贝,但不影响深拷贝   序列对象的切片其实是浅拷贝,即只拷贝顶级的对象   直接赋值:其实就是对象的引用(别名)。 浅拷贝(copy):拷贝父对象,不会拷贝对象的内部的子对象。 深拷贝(deepcopy): copy 模块的 deepcopy 方法,完全拷贝了父对象及其子对象。


华为软件测试笔试真题之变态逻辑推理题现在很多公司面试,都要求做笔试题。其中有软件测试的基本知识考察,也有不少逻辑推理题,不知道大家有没有遇到过,小编盆友之前面试华为过程中是有幸遇到了,今天整理了几道与大家一起分享下。2023年安徽选调生考试培训逻辑判断(6。23)1。聚苯乙烯泡沫塑料广泛用于制造一次性咖啡杯等用品,但其原料来自石油等不可再生能源,生成的聚苯乙烯高温条件下可能产生对人体有害组分,且无法自然降解,燃烧时还会造成环境污染。研究人员NBA赛季10大恶犯!詹皇把斯图尔特打满脸血排第一,KD约老师上榜北京时间6月22日,NBA赛季已经结束,今日美国媒体带来赛季总结,他们总结出了本赛季的十大恶犯。而这一次的赛季十大恶犯就引爆了热议,有很多超级巨星都出现在了其中,其中迅速榜上有名的福建边检事业发展史上首部发展规划出炉近日,厦门出入境边防检查总站结合实际出台十四五福建边检事业高质量发展实施意见(以下简称意见),配套出台出入境边防检查工作信息化建设机要密码装备建设装备建设4个专项实施意见,是福建边解放军4艘战舰接近美军基地,美机再逼近台岛由于美国海军在一周时间内连续出现了三起坠机事故,并且导致一架FA18EF超级大黄蜂战斗机,一架V22鱼鹰倾转旋翼机,一架SH60海鹰直升机的连续损失,这也使得美国海军从6月13日开十大元帅之首朱老总,在授衔时编号却是004,那么001是谁文星辰文史编辑长鹿前言新中国成立后的首次大授衔,此次仪式是给在革命的道路上做出过突出贡献的功臣们进行表彰和,朱德元帅在此次授衔在,成为了十大元帅之首,但让人没想到的是,在他的功勋章辽宁农民去世后,可以领取丧葬补助吗?有多少钱?在辽宁,参与基本养老保险的话,是可以领取丧葬补助的,如果参与的是职工养老保险,可以同时领取丧葬费和抚恤金,而参与的是城乡居民养老保险的话,只有个别地方才能领取到丧葬补助费。数据显示小苏打是治疗痛风最好的药?服用时,要知道这些事痛风是很多有不良饮食习惯和生活习惯的人可能会患有的疾病,随着经济社会的快速发展,人们的消费水平和生活质量越加提高,患有痛风的人群越来越多。不仅如此,痛风的患病人群也从中老年人逐渐趋不羁的灵魂关山飞度2月21日,俄罗斯总统普京向全体俄罗斯公民发表电视讲话。画面中,普京神情严肃,语调虽然清晰坚定,但却时不时地叹气。很显然,他正在做一个艰难且重要的决定。普京阐述了兄弟国家乌多家德媒恩昆库即将与莱比锡续约,6000万欧解约金条款明夏生效直播吧6月23日讯据德媒图片报踢球者的消息,莱比锡攻击手恩昆库即将与俱乐部续约。图片报和踢球者报道称,恩昆库已经就一份新合约与莱比锡达成一致,他将续约一年至2025年,续约后他的年中国奥委会2022年第36届奥林匹克日活动6月23日是国际奥林匹克日。国际奥委会于1948年设立奥林匹克日,旨在纪念现代奥林匹克运动的诞生,同时号召更多人加入到体育运动中来。中国奥委会第36届奥林匹克日活动以携手共创美好世
如何使用ArcGIS计算道路中心线概述在制图等应用的时候,有时需要将双线的面状道路提取中心线,转换为线状的道路。由于道路多为不规则的图形,提取难度比较高,加上能提取中心线的软件有限,更加增加了提取的难度。ArcGI不同散热设计的MagSafe充电座对iPhone无线充时的影响有多大?前言此前,充电头网已经对iPhone14系列的四款手机的直充和无线充方面皆做过相关的测试,其中直充的充电功率最高可达29。5W(搭配29W充电器),无线充电方面影响较大,因此皆取测索莱尔遗憾这场平局没能拉开与争冠对手之间的积分差距直播吧1月30日讯在北京时间今天凌晨结束的一场法甲联赛中,巴黎圣日耳曼在主场以11的比分被兰斯逼平。索莱尔本场比赛担任先发右边锋,赛后他在接受采访时表示球队有太多机会没有把握住,很ChatGPT的竞争对手Claude?1。Claude定义由OpenAI前员工共同创立的人工智能初创公司Anthropic已经悄悄地开始测试一个新的类似ChatGPT的人工智能助理,名叫Claude。Claude的目标电动牙刷真的比普通牙刷好吗?如何选择看这一篇就够了这是一个很常见的问题,也是许多人都想知道的答案。答案是电动牙刷可以比普通牙刷更有效地清洁牙齿,但也有一些限制。首先,电动牙刷可以更有效地清洁牙齿。由于电动牙刷的刷毛是振动的,它可以除了AdaLovelace架构TITAN,英伟达还在准备RTX4090Ti最近网络上爆出了AdaLovelace架构TITAN显卡的实物图,显示这款FoundersEdition显卡的厚度达到了四槽,挡板为金色,拥有三个DisplayPort端口和一个H汇丰晋信基金沈超全面注册制有利于A股市场长期表现魏昭宇中国证券报中证网中证网讯(记者魏昭宇)2月1日,证监会就全面实行股票发行注册制主要制度规则向社会公开征求意见。汇丰晋信基金宏观及策略师沈超认为,全面注册制实施,有望进一步提高曝OPPO一加将推7款1。5K柔性屏新机FindX6定位最高手机中国新闻1月31日,据数码博主数码闲聊站爆料,欧加系将推出7台1。5K柔性屏新机,其中定位最高的是FindX6系列,定位最低的则是塑料中框塑料后盖的中低端机。OPPOFindX中高端冰箱比普通冰箱好在哪?中高端冰箱和普通冰箱,价格不同,定位不同,自然有许多差异,任何产品都一样,高端产品必定比普通产品有一定的好处。就冰箱而言,中高端与普通冰箱差别还是比较大的。冰箱最基本的就是冷藏冷冻装修选家电,这4种别花冤枉钱买进口的了,选国产的质量好还省钱家用电器,是家庭生活中的必需品。很多人装修完新房,买家电时会投入很多,一味的去追求进口,认为进口家电就是好!其实,这是个误区。现在的国产家电技术已经很成熟了,特别是以下这4种,选国恭喜!中国短道速滑队1银2铜排名第4,头号劲敌独揽6金高居榜首北京时间2023年1月30日,德累斯顿短道速滑世青赛落幕,中国队在最后一个比赛日收获女子3000米接力银牌,以1枚银牌2枚铜牌的成绩结束本次比赛,在金牌榜上排名第4位。本次比赛共有