-
1. 激活你的Conda环境首先,你需要激活你想要升级Python版本的环境。假设你的环境名为myenv,你可以使用以下命令激活它:1conda activate myenv2. 升级Python版本然后,你可以使用conda install命令来升级Python版本。以下命令会将Python升级到3.8.x的最新版本:1conda install python=3.83. 验证升级升级完成后,你可以通过以下命令来验证Python版本是否已经成功升级:1python --version你应该会看到类似以下的输出,表示Python版本已经升级到3.8.x:1Python 3.8.x4. 处理依赖问题在升级Python版本后,可能会出现一些依赖包不兼容的情况。你可以使用以下命令来更新环境中的所有包,以确保它们与新版本的Python兼容:1conda update --all5. 测试环境最后,建议你运行一些测试代码,确保你的环境在升级后仍然正常工作。注意事项备份环境:在升级之前,建议你备份当前环境,以防升级过程中出现问题。你可以使用以下命令导出环境配置:1conda env export > environment.yml虚拟环境:如果你不想直接升级现有环境,可以考虑创建一个新的虚拟环境来测试Python 3.8,这样可以避免影响现有的项目。通过以上步骤,你应该能够成功将Conda环境中的Python版本从3.7.16升级到3.8。
-
编写一个 Python 程序,该程序将把用户的输入作为关键词,如亚马逊、极客博客等。然后在你的谷歌浏览器历史中搜索这个关键词,如果在任何一个网址中找到这个关键词,它就会删除它。比如,假设你输入了关键字‘geeksforgeeks’,那么它会搜索你的谷歌 chrome 历史,比如‘www . geekforgeks . org’,很明显这个 URL 包含了关键字‘geeksforgeeks’,那么它就会删除它,它还会搜索文章(比如“geeksforgeeks 是准备竞争性编程面试的好门户吗?”)标题中包含“geeksforgeeks”并删除它。首先,获取谷歌 chrome 历史文件在你的系统中的位置。注意:Google chrome 历史文件在 windows 中的位置一般为:C:\ Users \ manishkc \ AppData \ Local \ Google \ Chrome \ User Data \ Default \ History。完整代码1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859import sqlite3 # establish the connection with# history database file which is # located at given location# you can search in your system # for that location and provide # the path hereconn = sqlite3.connect("/path/to/History") # point out at the cursorc = conn.cursor() # create a variable id # and assign 0 initiallyid = 0 # create a variable result # initially as True, it will# be used to run while loopresult = True # create a while loop and put# result as our conditionwhile result: result = False # a list which is empty at first, # this is where all the urls will # be stored ids = [] # we will go through our database and # search for the given keyword for rows in c.execute("SELECT id,url FROM urls\ WHERE url LIKE '%geeksforgeeks%'"): # this is just to check all # the urls that are being deleted print(rows) # we are first selecting the id id = rows[0] # append in ids which was initially # empty with the id of the selected url ids.append((id,)) # execute many command which is delete # from urls (this is the table) # where id is ids (list having all the urls) c.executemany('DELETE from urls WHERE id = ?',ids) # commit the changes conn.commit() # close the connection conn.close()输出:(16886, 'https://www.geeksforgeeks.org/')方法补充使用Python清理Chrome浏览器的缓存和数据实现思路清理Chrome浏览器的缓存和数据,主要涉及以下几个步骤:找到Chrome浏览器的用户数据目录。删除或清空相关的缓存和数据文件。确保操作的安全性,避免误删用户重要数据。1. 找到Chrome的用户数据目录Chrome的用户数据目录通常位于以下路径:Windows: C:\Users\<username>\AppData\Local\Google\Chrome\User DatamacOS: /Users/<username>/Library/Application Support/Google/ChromeLinux: /home/<username>/.config/google-chrome2. 删除缓存和数据文件在用户数据目录中,可以找到缓存和其他文件。通常,缓存文件存储在Default/Cache和Default/Media Cache目录中。我们可以使用Python的os库和shutil库来进行文件操作。3. 实现代码示例以下是一个简单的Python示例,演示如何清理Chrome浏览器中的缓存:12345678910111213141516171819202122232425262728293031323334353637import osimport shutilimport platform # 确定用户数据目录def get_chrome_user_data_path(): system = platform.system() if system == "Windows": return os.path.join(os.getenv('LOCALAPPDATA'), 'Google', 'Chrome', 'User Data', 'Default') elif system == "Darwin": # macOS return os.path.join(os.path.expanduser('~'), 'Library', 'Application Support', 'Google', 'Chrome', 'Default') elif system == "Linux": return os.path.join(os.path.expanduser('~'), '.config', 'google-chrome', 'Default') else: raise Exception("Unsupported operating system") # 清理缓存def clear_chrome_cache(): user_data_path = get_chrome_user_data_path() cache_path = os.path.join(user_data_path, 'Cache') media_cache_path = os.path.join(user_data_path, 'Media Cache') # 检查缓存目录是否存在并删除 if os.path.exists(cache_path): shutil.rmtree(cache_path) print("清理缓存完成!") else: print("缓存目录不存在。") if os.path.exists(media_cache_path): shutil.rmtree(media_cache_path) print("清理媒体缓存完成!") else: print("媒体缓存目录不存在。") if __name__ == "__main__": clear_chrome_cache()代码解析首先,使用 platform.system() 来获取操作系统类型,这样可以动态设置用户数据目录。通过 os.path.join 构建缓存和媒体缓存的路径。使用 shutil.rmtree() 方法删除指定目录及其内容,完成缓存的清理。注意事项备份数据: 在执行清理操作前,请确保备份重要的浏览数据,避免误删。关闭Chrome: 清理缓存时,请确保Chrome浏览器已经关闭,以防止文件正在使用而无法删除。用 Python 清除 Chrome 缓存的指南清除 Chrome 缓存的步骤第一步:找到 Chrome 缓存目录在 Windows 系统中,Chrome 的缓存通常位于以下目录:C:\Users\<Your Username>\AppData\Local\Google\Chrome\User Data\Default\Cache在 macOS 系统中,则通常位于:/Users/<Your Username>/Library/Caches/Google/Chrome/Default第二步:编写 Python 代码清除缓存使用 Python 来删除这些缓存文件,可以自动化这个过程,大大提高效率。下面是一段代码示例,演示如何使用 Python 清除 Chrome 缓存:
-
一、pip简介pip是Python的包管理工具,全称为"Pip Installs Packages"。它是Python生态系统中最重要的工具之一,用于安装和管理Python第三方库。自Python 3.4和2.7.9版本起,pip已经作为标准组件与Python一同安装。二、pip的安装1.检查是否已安装pip在命令行中输入以下命令检查pip是否已安装:1pip --version或1pip3 --version如果显示版本信息,则表示已安装;如果未安装,可按以下方法安装。2.安装pip方法一:通过get-pip.py安装下载get-pip.py脚本:1curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py运行安装脚本:1python get-pip.py方法二:通过系统包管理器安装(Linux)Ubuntu/Debian:1sudo apt-get install python3-pipCentOS/RHEL:1sudo yum install python3-pip三、pip的基本使用安装包1pip install package_name例如安装requests库:1pip install requests安装特定版本1pip install package_name==version_number例如安装Django 2.2版本:1pip install django==2.2升级包1pip install --upgrade package_name卸载包1pip uninstall package_name查看已安装的包1pip list查看包详情1pip show package_name搜索包1pip search "query"注意:从pip 20.3开始,移除了search命令,建议直接访问PyPI网站搜索。四、高级用法1.从requirements.txt安装1pip install -r requirements.txt2.生成requirements.txt1pip freeze > requirements.txt3.使用国内镜像源加速国内用户可以使用以下镜像源加速下载:阿里云:https://mirrors.aliyun.com/pypi/simple/清华大学:https://pypi.tuna.tsinghua.edu.cn/simple/中国科技大学:https://pypi.mirrors.ustc.edu.cn/simple/临时使用:1pip install -i https://mirrors.aliyun.com/pypi/simple/ package_name永久配置:1pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/4. 创建虚拟环境并安装包1234python -m venv myenv # 创建虚拟环境source myenv/bin/activate # 激活虚拟环境(Linux/Mac)myenv\Scripts\activate # 激活虚拟环境(Windows)pip install package_name # 在虚拟环境中安装包五、常见问题解决权限问题:在Linux/Mac上,如果遇到权限错误,可以尝试:1pip install --user package_name版本冲突:使用虚拟环境隔离不同项目的依赖安装失败:尝试更新pip:1pip install --upgrade pip缓存问题:清除pip缓存:1pip cache purge六、最佳实践始终在虚拟环境中工作,避免污染全局Python环境使用requirements.txt记录项目依赖定期更新依赖包以获取安全补丁和新功能在生产环境中固定依赖版本以避免意外更新导致的兼容性问题
-
一、数据类型分类Python3 中常见的数据类型有:Number(数字)String(字符串)bool(布尔类型)List(列表)Tuple(元组)Set(集合)Dictionary(字典)Python3 的六个标准数据类型中:不可变数据(3 个): Number(数字)、String(字符串)、Tuple(元组);可变数据(3 个): List(列表)、Dictionary(字典)、Set(集合)。基本Number(数字)String(字符串)多字段List(列表)Tuple(元组)Dictionary(字典)Set(集合)1234567891011# List(列表)my_list = [0, 1, 2, 3, 4, 5, 6, 7, 8] # Tuple(元组)(值不能修改)my_tuple = (1, 2, 3, 4) # Dictionary(字典)my_info = {'name': '张三', 'age': 18, 'address': '北京市'} # Set(集合)set01 = {1, 2, 3, 4} 二、基本数据类型1、Number(数字)Python3 支持 int、float、bool、complex(复数)。在Python 3里,只有一种整数类型 int,表示为长整型,没有 python2 中的 Long。像大多数语言一样,数值类型的赋值和计算都是很直观的。内置的type()函数可以用来查询变量所指的对象类型。Python可以同时为多个变量赋值,如a, b = 1, 2。一个变量可以通过赋值指向不同类型的对象。数值的除法包含两个运算符:/ 返回一个浮点数,// 返回一个整数。在混合计算时,Python会把整型转换成为浮点数1234567891011121314>>> 5 + 4 # 加法9>>> 4.3 - 2 # 减法2.3>>> 3 * 7 # 乘法21>>> 2 / 4 # 除法,得到一个浮点数0.5>>> 2 // 4 # 除法,得到一个整数0>>> 17 % 3 # 取余 2>>> 2 ** 5 # 乘方322、String(字符串)反斜杠可以用来转义,使用r可以让反斜杠不发生转义。字符串可以用+运算符连接在一起,用*运算符重复。Python中的字符串有两种索引方式,从左往右以0开始,从右往左以-1开始。Python中的字符串不能改变。12345678910111213print(str[0:-1]) # 打印字符串第一个到倒数第二个字符(不包含倒数第一个字符)print(str[0]) # 打印字符串的第一个字符print(str[2:5]) # 打印字符串第三到第五个字符(包含第五个字符)print(str[2:]) # 打印字符串从第三个字符开始到末尾 str_01 = 'my name is:{}, age:{}'print(str_01.format('张三', 18)) str_02 = 'my name is:{name}, age:{age}'print(str_02.format(name='张三', age=18)) str_03 = 'my name is:{name}, age:{age}'print(str_03.format_map({'name': '张三', 'age': 18}))Python 使用反斜杠\ 转义特殊字符,如果你不想让反斜杠发生转义,可以在字符串前面添加一个r,表示原始字符串:12345print('Ru\noob')Ruoobprint(r'Ru\noob')Ru\noobencode()、decode()方法encode() 方法以指定的编码格式编码字符串。errors参数可以指定不同的错误处理方案。decode() 方法以指定的编码格式解码 bytes 对象。默认编码为 ‘utf-8’。该方法返回编码后的字符串,它是一个 bytes 对象。12str.encode(encoding='UTF-8',errors='strict')bytes.decode(encoding="utf-8", errors="strict")encoding – 要使用的编码,如: UTF-8。errors – 设置不同错误的处理方案。默认为 ‘strict’,意为编码错误引起一个UnicodeError。 其他可能得值有 ‘ignore’, ‘replace’, ‘xmlcharrefreplace’, ‘backslashreplace’ 以及通过 codecs.register_error() 注册的任何值。1234567891011#!/usr/bin/python3 str = "菜鸟教程"str_utf8 = str.encode("UTF-8", 'strict')str_gbk = str.encode("GBK") print("UTF-8 编码:", str_utf8)print("GBK 编码:", str_gbk) print("UTF-8 解码:", str_utf8.decode('UTF-8'))print("GBK 解码:", str_gbk.decode('GBK', 'strict'))结果:1234UTF-8 编码: b'\xe8\x8f\x9c\xe9\xb8\x9f\xe6\x95\x99\xe7\xa8\x8b'GBK 编码: b'\xb2\xcb\xc4\xf1\xbd\xcc\xb3\xcc'UTF-8 解码: 菜鸟教程GBK 解码: 菜鸟教程3.2 format格式化字符串12345678910111213# 1、print('{}网址: "{}!"'.format('菜鸟教程', 'www.runoob.com'))# 2、print('{name}网址: {site}'.format(name='菜鸟教程', site='www.runoob.com')) # 3、print('{0} 和 {1}'.format('Google', 'Runoob'))# 可以任意组合print('站点列表 {0}, {1}, 和 {other}。'.format('Google', 'Runoob', other='Taobao')) # 4、table = {'Google': 1, 'Runoob': 2, 'Taobao': 3}print('Runoob: {0[Runoob]:d}; Google: {0[Google]:d}; Taobao: {0[Taobao]:d}'.format(table))3、Bool(布尔类型)布尔类型即 True 或 False。在 Python 中,True 和 False 都是关键字,表示布尔值。布尔类型可以用来控制程序的流程,比如判断某个条件是否成立,或者在某个条件满足时执行某段代码。布尔类型特点:布尔类型只有两个值:True 和 False。布尔类型可以和其他数据类型进行比较,比如数字、字符串等。在比较时,Python 会将 True 视为 1,False 视为 0。布尔类型可以和逻辑运算符一起使用,包括 and、or 和 not。这些运算符可以用来组合多个布尔表达式,生成一个新的布尔值。布尔类型也可以被转换成其他数据类型,比如整数、浮点数和字符串。在转换时,True 会被转换成 1,False 会被转换成 0。12345678910111213141516a = Trueb = False # 比较运算符print(2 < 3) # Trueprint(2 == 3) # False # 逻辑运算符print(a and b) # Falseprint(a or b) # Trueprint(not a) # False # 类型转换print(int(a)) # 1print(float(b)) # 0.0print(str(a)) # "True"Python3 中,bool是 int 的子类,True和False可以和数字相加,True==1、False==0会返回True,但可以通过is来判断类型。123456a1 = Trueprint(type(a1))print(a1 + 100) <class 'bool'>1014、Bytes字符串转为Bytes12# 解析为bytes:b'Hello,World'print('Hello,World'.encode())Bytes转为字符串123456789# 创建一个bytes对象bytes_data = b'Hello, World!' # b'Hello, World!'print(bytes_data) # 将bytes对象转换为字符串string_data = bytes_data.decode('utf-8')print(string_data)三、多值存储1、List(列表)增、删、改、查:1234567891011121314151617181920212223my_list = [0, 1, 2, 3, 4, 5, 6, 7, 8]# 1、增my_list.append('333')# 将另一个集合中添加到列表中insert_list = [1, 23]my_list.extend(insert_list)# 指定位置前插入元素my_list.insert(2, '34') # 2、删my_list.remove() # 3、改my_list[1] = '张三' # 4、查# 查看是否存在于集合中print('张三' in my_list)# 查询所在索引my_list.index('张三')my_list.index('张三', 1, 4)# 查询数量my_list.count('张三')其它1234567891011# 循环for one in my_list: # print(one) print(one, end='==') print(one, end='==\n%%% ') # 排序# 排序-正序my_list.sort()# 排序-倒叙my_list.sort(reverse=True)函数内置方法方法序号list.append(obj)在列表末尾添加新的对象list.count(obj)统计某个元素在列表中出现的次数list.extend(seq)在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)list.index(obj)从列表中找出某个值第一个匹配项的索引位置list.insert(index, obj)将对象插入列表list.pop([index=-1\])移除列表中的一个元素(默认最后一个元素),并且返回该元素的值list.remove(obj)移除列表中某个值的第一个匹配项list.reverse()反向列表中元素list.sort( key=None, reverse=False)对原列表进行排序list.clear()清空列表list.copy()复制列表2、Tuple(元组)Python的元组与列表类似,不同之处在于元组的元素不能修改。12345678910# tuple元组my_tuple = (1, 2, 3, 4) # 查-某个值print(my_tuple[1]) # 查—查询所在索引位置(前闭右开区间)(起始索引:0)print(my_tuple.index(2, 1, 3))# 查-某值数量print(my_tuple.count(1))Python元组包含了以下内置函数函数方法及描述实例len(tuple)计算元组元素个数>>> tuple1 = ('Google', 'Runoob', 'Taobao')max(tuple)返回元组中元素最大值max(tuple2)min(tuple)返回元组中元素最小值min(tuple2)tuple(iterable)将可迭代系列转换为元组tuple1=tuple(['Google', 'Taobao', 'Runoob', 'Baidu'])3、Dictionary(字典)增删改查123456789101112131415161718192021222324my_info = {'name': '张三', 'age': 18, 'address': '北京市'}# 1、查询元素# 查-查询单个(无值异常)print(my_info['name'])print(my_info['age'])# 查-查询单个(无值返回 None)print(my_info.get('name1'))# 查-查询单个(无值返回 指定值)print(my_info.get('name2', '李四')) # 2、修改元素my_info['name'] = '王五' # 3、添加元素# 添加元素-键不存在则添加my_info['id'] = 1234 # 4、删除元素# 删除元素-删除单个元素del my_info['id']# 删除-删除字典(查询会报错del my_info# 删除—清空字段(值为{})my_info.clear()其它API123456789101112# 5、其它API# 测量字典中,键值对的个数print(len(my_info)) # 返回一个包含字典所有KEY的列表print(my_info.keys()) # 返回一个包含字典所有value的列表print(my_info.values()) # 返回一个包含所有(键,值)元祖的列表print(my_info.items())方法函数及描述dict.clear()删除字典内所有元素dict.copy()返回一个字典的浅复制dict.fromkeys()创建一个新字典,以序列seq中元素做字典的键,val为字典所有键对应的初始值dict.get(key, default=None)返回指定键的值,如果键不在字典中返回 default 设置的默认值key in dict如果键在字典dict里返回true,否则返回falsedict.items()以列表返回一个视图对象dict.keys()返回一个视图对象dict.setdefault(key, default=None)类似, 但如果键不存在于字典中,将会添加键并将值设为defaultdict.update(dict2)把字典dict2的键/值对更新到dict里dict.values()返回一个视图对象pop(key[,default\])删除字典 key(键)所对应的值,返回被删除的值。popitem()返回并删除字典中的最后一对键和值。4、Set(集合)集合(set)是一个无序的不重复元素序列。集合中的元素不会重复,并且可以进行交集、并集、差集等常见的集合操作。可以使用大括号 { } 创建集合,元素之间用逗号 , 分隔, 或者也可以使用 set() 函数创建集合。12345678910111213141516171819202122232425# 0、创建集合set01 = {1, 2, 3, 4} # 直接使用大括号创建集合set02 = set([4, 5, 6, 7]) # 使用 set() 函数从列表创建集合 # 1、增# 1-1 将元素 x 添加到集合 s 中,如果元素已存在,则不进行任何操作。set01.add(100)# 1-2 添加元素,且参数可以是列表,元组,字典等set01.update([1, 2, ]) # 2、删# 2-1 将元素 x 从集合 s 中移除,如果元素不存在,则会发生错误set01.remove(1)# 2-2 移除集合中的元素,且如果元素不存在,不会发生错误set01.discard(1)# 2-3 随机删除集合中的一个元素s.pop() # 3、其它# 判断元素是否在集合内(False)print('1' in set03)# 计算集合元素个数print(len(set01))# 清空集合set01.clear()集合内置方法完整列表方法描述add()为集合添加元素clear()移除集合中的所有元素copy()拷贝一个集合difference()返回多个集合的差集difference_update()移除集合中的元素,该元素在指定的集合也存在。discard()删除集合中指定的元素intersection()返回集合的交集intersection_update()返回集合的交集。isdisjoint()判断两个集合是否包含相同的元素,如果没有返回 True,否则返回 False。issubset()判断指定集合是否为该方法参数集合的子集。issuperset()判断该方法的参数集合是否为指定集合的子集pop()随机移除元素remove()移除指定元素symmetric_difference()返回两个集合中不重复的元素集合。symmetric_difference_update()移除当前集合中在另外一个指定集合相同的元素,并将另外一个指定集合中不同的元素插入到当前集合中。union()返回两个集合的并集update()给集合添加元素len()计算集合元素个数四、其它1、Json方法作用返回类型eval(字符串表达式)eval() 函数用来执行一个【字符串表达式】,并返回表达式的值。list、dict、tuplejson.dumps()将python对象编码成Json字符串返回json字符串json.loads()将Json字符串解码成python对象返回python对象json.dump()将python中的对象转化成json储存到文件中无返回json.load()将文件中的json的格式转化成python对象提取出来返回python对象五、其它函数1、print()1print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)objects :复数,表示可以一次输出多个对象。输出多个对象时,需要用 , 分隔。sep :用来间隔多个对象,默认值是一个空格。end :用来设定以什么结尾。默认值是换行符 \n,我们可以换成其他字符串。file :要写入的文件对象。flush :输出是否被缓存通常决定于 file,但如果 flush 关键字参数为 True,流会被强制刷新。123456# 1 2 3 4 5print('1', '2', '3', '4', '5')# 1+2+3print('1', '2', '3', sep='+')# 1++2++3==print('1', '2', '3', sep='++', end='==')
-
1. threading.Lock()(线程锁)用于在多线程环境下防止多个线程同时访问共享资源。示例:多个线程访问共享变量1234567891011121314151617181920212223242526import threadingimport time counter = 0 # 共享变量lock = threading.Lock() # 创建锁 def worker(n): global counter with lock: # 获取锁 local_counter = counter time.sleep(0.1) # 模拟某些计算 counter = local_counter + n print(f"Thread {threading.current_thread().name} updated counter to {counter}") # 创建多个线程threads = [threading.Thread(target=worker, args=(1,)) for _ in range(5)] # 启动线程for t in threads: t.start() # 等待所有线程完成for t in threads: t.join() print("Final counter value:", counter)threading.Lock() 工作机制lock.acquire(): 获取锁(如果锁已被占用,则阻塞)lock.release(): 释放锁(让其他线程可以获取)with lock:: 推荐的用法,with 语句确保锁在退出代码块时自动释放,即使发生异常。2. multiprocessing.Lock()(进程锁)用于多进程环境,防止多个进程同时访问共享资源。示例:多个进程访问共享资源12345678910111213141516171819202122232425import multiprocessingimport time counter = multiprocessing.Value('i', 0) # 共享变量lock = multiprocessing.Lock() # 进程锁 def worker(n): with lock: # 获取锁 local_counter = counter.value time.sleep(0.1) # 模拟某些计算 counter.value = local_counter + n print(f"Process {multiprocessing.current_process().name} updated counter to {counter.value}") # 创建多个进程processes = [multiprocessing.Process(target=worker, args=(1,)) for _ in range(5)] # 启动进程for p in processes: p.start() # 等待所有进程完成for p in processes: p.join() print("Final counter value:", counter.value)multiprocessing.Lock() 工作机制multiprocessing.Lock() 和 threading.Lock() 接口相同,但作用于进程间。with lock: 确保进程互斥访问共享资源,防止数据不一致问题。3. RLock()(可重入锁)适用于递归调用或同一线程多次获取锁123456789101112import threading lock = threading.RLock() def recursive_function(n): if n <= 0: return with lock: # 允许同一线程多次获取锁 print(f"Acquired lock in recursion level {n}") recursive_function(n - 1) recursive_function(3)普通 Lock 不能被同一线程多次 acquire(),但 RLock() 可以!4. Semaphore()(信号量)用于限制并发访问的线程/进程数量(例如:数据库连接池)。123456789101112131415161718import threadingimport time semaphore = threading.Semaphore(3) # 最多允许 3 个线程同时运行 def worker(n): with semaphore: print(f"Thread {n} is running") time.sleep(2) print(f"Thread {n} finished") threads = [threading.Thread(target=worker, args=(i,)) for i in range(6)] for t in threads: t.start() for t in threads: t.join()设定 Semaphore(3),最多 3 个线程能同时进入。常用于连接池、资源管理、并发限制等场景。5. Condition()(条件变量)用于线程间协调,例如一个线程需要等另一个线程完成某个操作后才能继续。123456789101112131415161718192021222324252627import threading condition = threading.Condition()shared_data = None def consumer(): global shared_data with condition: print("Consumer waiting...") condition.wait() # 等待生产者通知 print(f"Consumer received: {shared_data}") def producer(): global shared_data with condition: shared_data = "Data ready!" print("Producer produced data, notifying consumer...") condition.notify() # 通知消费者 t1 = threading.Thread(target=consumer)t2 = threading.Thread(target=producer) t1.start()t2.start() t1.join()t2.join()使用 Condition() 解决“生产者-消费者”问题。6. Event()(事件)线程间的简单信号通知机制(相当于全局 flag)12345678910111213141516import threadingimport time event = threading.Event() def worker(): print("Worker waiting for event...") event.wait() # 等待事件被 set print("Worker received event signal!") def set_event(): time.sleep(3) event.set() # 触发事件 threading.Thread(target=worker).start()threading.Thread(target=set_event).start()适用于:线程间同步控制多个线程的启动时机
-
什么是解包先别急着划走,这不是你想的 “哦!我早会了” 的那种。来个简单例子热热身:123a, b = [1, 2]print(a) # 1print(b) # 2这就是最常见的解包操作。Python把右边的列表拆开,把值分别赋给左边的变量。但是!你以为就这点花活?那可就太小看解包了。多层解包:不只是解开“表层”有一次我在处理一个嵌套的数据结构,写着写着就头晕了,然后突然灵光一闪:123456data = ("花姐", (28, "Python博主")) name, (age, title) = dataprint(name) # 花姐print(age) # 28print(title) # Python博主这其实是多层解包,一行搞定,专业又不失优雅。但是如果你还在用下标访问,那未免有点费劲:123name = data[0]age = data[1][0]title = data[1][1]这不是写代码,这是折腾自己。星号 * 解包:别小看这个“星号”很多人知道它可以用在函数参数上,比如:12345def greet(*args): for arg in args: print(f"Hi {arg}") greet("花姐", "读者朋友", "小黑猫")但你可能没注意,它还可以用在变量赋值上:1234first, *middle, last = [1, 2, 3, 4, 5]print(first) # 1print(middle) # [2, 3, 4]print(last) # 5这个在处理不定长度的序列时特别爽,用过的都说 “真香” 。解包操作的性能测试技术博主嘛,不测性能总感觉文章不够硬。我搞了一个小测试:12345678910111213141516import time lst = list(range(1000000)) # 解包start = time.time()a, *b = lstend = time.time()print("解包耗时:", end - start) # 切片start = time.time()a = lst[0]b = lst[1:]end = time.time()print("切片耗时:", end - start)运行结果:解包耗时: 0.007996559143066406切片耗时: 0.01676344871520996这时候很多人就会下结论说:“诶?那看来解包还比切片快呀!”但,先别急,这结论下得太早了,就像看到某人微信头像是猫,就说他肯定撸猫达人,说不定人家只是懒得换头像罢了。为什么感觉“切片比解包慢”?其实你被假象骗了!前面我们做了一个性能测试,结果显示解包更快但先别急着站队,咱得搞清楚——这两个操作本质上干的事情就不一样!来看对比代码:123456# 解包a, *b = lst # 把第一个元素单独取出来,其余自动打包成列表 b # 切片a = lst[0]b = lst[1:] # 拿出第一个元素 + 手动切片构建新列表虽然表面看是一样的结果,但背后差了不少事儿:操作背后干了什么解包解释器做了优化,生成新列表的过程相对高效切片.copy() 了一个子列表,需要分配内存、复制元素等操作所以,解包有点像“偷偷快了一点”,但不是它真有多猛,而是Python帮它抄了点近路。更严谨的测试方式推荐刚才我们用 time.time() 粗测一轮其实参考价值有限,来,用 timeit 试试更科学的方式:123456import timeit setup = "lst = list(range(1000000))" print("解包耗时:", timeit.timeit("a, *b = lst", setup=setup, number=10))print("切片耗时:", timeit.timeit("a = lst[0]; b = lst[1:]", setup=setup, number=10))这个测试你多跑几次,会发现:解包不一定总快,有时候差距其实很小数据量越大,切片复制带来的开销越明显小结一下:解包 vs 切片,不是谁“性能更强”,而是看你“用在什么地方”。1.用解包:要快速拆第一项或最后一项不需要太精确地控制中间部分更喜欢语法糖的简洁2.用切片:需要处理特定区间的数据对性能特别敏感时数据结构复杂,解包可读性反而下降时一句话总结:解包适合“拿一点留一堆”,切片适合“精准控制拿哪段”。别被表面的耗时骗了,就像听说隔壁老王做副业月入十万,你不能直接辞职——得搞清楚人家到底干了啥 易被忽略的坑点小贴士时间到了,以下这些细节,真的是很多Python开发者都会忽略的:1. 解包不能比右边变量多12a, b = [1]# ValueError: not enough values to unpack (expected 2, got 1)这个报错谁没遇到过?我第一次见到它的时候还以为是编辑器出bug了,重启了IDE才发现是自己菜 2. 解包对象必须是可迭代的12a, b = None# TypeError: cannot unpack non-iterable NoneType object别问我怎么知道的,那天debug一个空返回值的时候差点把键盘砸了。3. 字典解包的顺序不是你想的那样12a, b = {'x': 1, 'y': 2}print(a, b) # x y你以为解的是值,其实解的是 key。要值?得 .values() 啊哥:12a, b = {'x': 1, 'y': 2}.values()print(a, b) # 1 2实战场景:解包的实际用法有次我写爬虫,需要从元组列表中提取字段:12345678data = [ ("Python", 95), ("Java", 85), ("Go", 75)] for lang, score in data: print(f"{lang} 的得分是 {score}")这要是你还在手动 data[i][j],那你可能真的没理解Python的“优雅”。再比如交换两个变量的值,常规写法要用临时变量对吧:123temp = aa = bb = tempPython直接来个:1a, b = b, a看到这里,连我那只平时只知道趴在路由器上取暖的猫都叫了一声“妙啊”。解包 + 函数参数 = 神操作你可以用 * 和 ** 解包参数:12345def show(name, age): print(f"{name} - {age}") args = ("花姐", 28)show(*args)字典也行:12kwargs = {"name": "花姐", "age": 28}show(**kwargs)
-
一、len():字符串的"测谎仪"len()方法就像X光扫描仪,能瞬间穿透字符串表面,精确测量其字符数量。核心特性:Unicode精准计算:无论中英文,每个字符都算作1个长度单位转义字符透明:\n、\t等特殊字符按单个计算时间复杂度O(1):直接读取内部长度标识,无需遍历实战案例:12text = "Hello\n世界!🚀"print(len(text)) # 输出:9(H e l l o \n 世 界 !🚀)进阶技巧:验证用户输入:if len(password) < 8:批量处理控制:for i in range(0, len(text), 100):性能监控:def log_size(msg): print(f"Log length: {len(msg)}")二、split():字符串的"解剖刀"split()方法如同手术刀,能将字符串按指定分隔符精准切割。参数解析:参数说明示例sep分隔符(默认空格)"a,b,c".split(",") → ['a','b','c']maxsplit最大分割次数"a b c".split(maxsplit=1) → ['a','b c']实战场景:CSV解析:123line = "Name,Age,City\nAlice,30,New York"headers, data = line.split('\n')columns = headers.split(',')日志分析:12log = "[ERROR] File not found: data.txt"level, message = log.split(']', 1)[1].split(':', 1)注意事项:空字符串陷阱:"".split() → []连续分隔符处理:"a,,b".split(',') → ['a', '', 'b']特殊字符转义:r"path\to\file".split('\\')三、join():字符串的"缝合怪"join()方法像基因编辑技术,能将可迭代对象中的元素无缝连接。性能优势:比+运算符快6-8倍(避免创建中间字符串)内存效率提升50%+(预计算总长度)实战案例:生成SQL语句:123ids = [1, 2, 3]query = "SELECT * FROM users WHERE id IN (" + ",".join(map(str, ids)) + ")"# 输出:SELECT * FROM users WHERE id IN (1,2,3)构建HTML列表:12items = ["Apple", "Banana", "Cherry"]html = "<ul>\n" + "\n".join([f"<li>{item}</li>" for item in items]) + "\n</ul>"二进制协议打包:123header = b"\x01\x02\x03"payload = b"DATA"packet = header + b"\x00".join([header, payload])高级技巧:类型转换:''.join(map(str, [1, True, 3.14])) → "1True3.14"路径拼接:os.path.join()的替代方案(跨平台安全)编码转换:bytes.join(b'', [s.encode() for s in list])四、组合技法:三剑客联合作战场景1:日志清洗12345678log_entry = "127.0.0.1 - - [10/Oct/2023:13:55:36 +0000] \"GET / HTTP/1.1\" 200 2326" # 分割关键字段parts = log_entry.split()ip, timestamp, request = parts[0], parts[3][1:-1], parts[5] # 重建结构化数据cleaned = f"{ip} | {timestamp} | {request}"场景2:命令行参数解析12345678910args = "--input data.csv --output result.json --verbose" # 分割参数params = args.split('--')[1:] # 构建字典config = {}for param in params: key, value = param.split(maxsplit=1) config[key.strip()] = value.strip() if value else True场景3:自然语言处理1234567891011sentence = "自然语言处理是人工智能的重要领域。" # 分词处理words = sentence.split() # 去除停用词stopwords = {"是", "的"}filtered = [word for word in words if word not in stopwords] # 重建句子processed = " ".join(filtered)五、常见错误与解决方案类型错误:12345# 错误:join()参数必须为字符串可迭代对象''.join(123) # TypeError # 解决:显式转换类型''.join(map(str, [1, 2, 3]))空值处理:12345# 错误:split()可能产生空字符串"".split(',') # 返回[''] # 解决:过滤空值[x for x in text.split(',') if x]编码问题:12345# 错误:混合字节串和字符串b'data'.join(['a', 'b']) # TypeError # 解决:统一类型''.join([s.decode() for s in byte_list])六、性能优化秘籍预分配内存:1234567# 低效方式result = ""for s in list: result += s # 高效方式result = ''.join(list)生成器表达式:1234# 内存友好型处理大文件with open('bigfile.txt') as f: chunks = (f.read(1024) for _ in range(100)) content = ''.join(chunks)并行处理:123456789from concurrent.futures import ThreadPoolExecutor def process_chunk(chunk): return chunk.upper() with ThreadPoolExecutor() as executor: processed = list(executor.map(process_chunk, big_list)) final = ''.join(processed)
-
Python 中的 zip() 函数是一个高效且简洁的工具,用于将多个可迭代对象(如列表、元组等)的元素按位置配对,生成一个元组迭代器。以下是详细解析:核心功能将多个可迭代对象的元素按顺序组合成元组,返回一个迭代器。例如:list1 = [1, 2, 3] list2 = ["a", "b", "c"] zipped = zip(list1, list2) print(list(zipped)) # 输出:[(1, 'a'), (2, 'b'), (3, 'c')] 关键特性按需生成:zip() 返回迭代器,不会一次性生成所有组合,适合处理大数据。最短优先原则:输出长度由最短的输入可迭代对象决定:a = [1, 2, 3] b = ["a", "b"] print(list(zip(a, b))) # 输出:[(1, 'a'), (2, 'b')] 支持任意数量输入:names = ["Alice", "Bob", "Charlie"] ages = [25, 30, 35] cities = ["New York", "London", "Paris"] for name, age, city in zip(names, ages, cities): print(f"{name} is {age} and lives in {city}") 常见用法1. 遍历多个序列keys = ["name", "age", "city"] values = ["Alice", 30, "New York"] for k, v in zip(keys, values): print(f"{k}: {v}") # 输出: # name: Alice # age: 30 # city: New York 2. 转置矩阵(行列互换)matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] transposed = list(zip(*matrix)) print(transposed) # 输出:[(1, 4, 7), (2, 5, 8), (3, 6, 9)] 3. 解压序列pairs = [(1, "a"), (2, "b"), (3, "c")] numbers, letters = zip(*pairs) print(numbers) # 输出:(1, 2, 3) print(letters) # 输出:('a', 'b', 'c') 4. 与字典结合keys = ["a", "b", "c"] values = [1, 2, 3] d = dict(zip(keys, values)) print(d) # 输出:{'a': 1, 'b': 2, 'c': 3} 注意事项类型一致性:输入可以是列表、元组、字符串等可迭代对象,但元素类型无需一致。迭代器特性:zip() 对象只能遍历一次,重复使用需重新生成。Python 3 vs Python 2:Python 3 中 zip() 返回迭代器,Python 2 返回列表。替代方案若需列表而非迭代器,用 list(zip(...))。若需处理不等长序列,可用 itertools.zip_longest:from itertools import zip_longest a = [1, 2, 3] b = ["a", "b"] print(list(zip_longest(a, b, fillvalue="None"))) # 输出:[(1, 'a'), (2, 'b'), (3, 'None')] 通过 zip(),Python 提供了一种简洁高效的方式处理多序列的并行操作,是数据处理和函数式编程中的常用工具。
-
Python 中的 queue 模块和 Celery 队列是两种不同场景下的任务队列解决方案,主要区别体现在架构、用途和功能上:1. 架构与用途特性queue 模块Celery核心定位线程安全的内存队列分布式任务队列框架主要用途多线程/进程间通信异步任务处理、定时任务、分布式计算依赖组件Python 标准库(无需额外依赖)需消息代理(RabbitMQ/Redis等)典型场景单机多线程任务分发跨服务器/进程的大规模任务调度2. 功能对比功能queue 模块Celery任务持久化内存存储(程序重启后丢失)支持持久化到数据库/消息代理任务重试机制需手动实现内置重试逻辑(可配置重试次数和间隔)任务结果追踪需自行记录内置结果后端(支持多种存储方案)并发模型依赖线程/进程支持多 Worker 进程/服务器并行监控与管理无内置工具提供命令行工具、Flower 监控界面定时任务需结合 threading.Timer 实现内置周期性任务调度(Beat 服务)3. 性能与扩展性特性queue 模块Celery吞吐量适合轻量级任务适合高并发、大规模任务扩展性仅支持单机多线程支持横向扩展(多 Worker 多服务器)容错性无容错机制(进程崩溃则任务丢失)支持任务重试、消息确认机制资源消耗内存级开销需额外维护消息代理服务4. 代码示例对比使用 queue 实现生产者-消费者模型from queue import Queue import threading def worker(q): while True: item = q.get() print(f"Processing {item}") q.task_done() q = Queue() threads = [] for _ in range(3): t = threading.Thread(target=worker, args=(q,)) t.start() threads.append(t) for item in ["task1", "task2", "task3"]: q.put(item) q.join() for t in threads: t.join() 使用 Celery 实现异步任务# tasks.py from celery import Celery app = Celery('tasks', broker='redis://localhost:6379/0') @app.task def process_task(item): return f"Processed {item}" # 调用任务 result = process_task.delay("task1") print(result.get(timeout=10)) # 获取任务结果 选择建议用 queue 的场景:单机多线程/进程间简单任务分发无需持久化或复杂管理的轻量级需求快速实现生产者-消费者模型用 Celery 的场景:需要分布式任务处理的 Web 应用(如发送邮件、处理图片)任务需持久化、重试、监控系统需横向扩展(多台服务器协同工作)如果只需单机内简单的任务队列,queue 足够高效;若需构建可扩展的异步任务系统,Celery 是更专业的选择。
-
资源购买资源名称规格操作系统存储ECS鲲鹏内存优化型 km1.xlarge.8 4vCPUs 32GiBHuawei Cloud EulerOS 2.0 标准版 64位 ARM版系统盘:超高IO,100GiB基础软件安装Condamkdir -p ~/miniconda3 wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-aarch64.sh -O ~/miniconda3/miniconda.sh bash ~/miniconda3/miniconda.sh -b -u -p ~/miniconda3 rm -f ~/miniconda3/miniconda.sh source ~/miniconda3/bin/activate conda init --allPython & Pip官方默认安装的python版本为3.99,版本比较低,这里使用Conda创建一个3.10的虚拟环境。conda create -n QAnything python=3.10 conda activate QAnything # 设置 pip软件源 pip config set global.index-url https://repo.huaweicloud.com/repository/pypi/simple python -m pip install --upgrade pipDocker & Docker Compose官方默认安装的docker版本为18.09.0,版本比较低,很多新的特性无法使用,如docker-buildx等,建议升级到最新版本。因为官方并未提供Huawei Cloud EulerOS 2.0的repo支持,所以可以采取以下方式进行安装。如果之前安装过docker,要先删掉之后再安装依赖sudo dnf remove docker docker-ce-cli docker-selinux docker-engine下载repo文件wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.huaweicloud.com/docker-ce/linux/centos/docker-ce.repo sudo sed -i 's+download.docker.com+mirrors.huaweicloud.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo sudo sed -i 's+$releasever+9.9+' /etc/yum.repos.d/docker-ce.repo安装新版本sudo dnf install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin设置开机启动sudo systemctl enable --now docker配置镜像加速器vi /etc/docker/daemon.json # 粘贴以下配置,保存退出,镜像地址可替换成自己在华为云申请的镜像加速器地址 { "registry-mirrors": [ "https://docker.1ms.run", "https://docker.xuanyuan.me"] } 重启dockersystemctl restart docker下载QAnything源码git clone https://github.com/netease-youdao/QAnything.git官方的docker镜像xixihahaliu01/qanything-linux:v1.5.1 是在X86的服务器下构建的,无法在ARM架构下运行,需要手动构建Docker镜像。构建QAnything镜像进入build_images,查看Dockerfile,可以得到以下几点信息Dockerfile文件要移动到父目录下才能构建需要准备models、nltk_data文件夹数据# 复制 requirements.txt 文件到容器中 COPY requirements.txt /tmp/requirements.txt # 复制 models 文件夹到 /root 目录 COPY models /root/models COPY nltk_data /root/nltk_data想知道model文件夹下要准备什么数据就要看这个文件复制到容器后是如何使用的,通过docker-compose-linux.yaml 可知,运行qanything-container-local容器时会执行/bin/bash -c "cd /workspace/QAnything && bash scripts/entrypoint.sh",打开script/entrypoint.sh,其中跟/root/models和/root/nltk_data有关的信息如下:# 创建软连接 if [ ! -L "/workspace/QAnything/qanything_kernel/dependent_server/embedding_server/embedding_model_configs_v0.0.1" ]; then # 如果不存在软连接 cd /workspace/QAnything/qanything_kernel/dependent_server/embedding_server && ln -s /root/models/linux_onnx/embedding_model_configs_v0.0.1 . fi if [ ! -L "/workspace/QAnything/qanything_kernel/dependent_server/rerank_server/rerank_model_configs_v0.0.1" ]; then # 如果不存在软连接 cd /workspace/QAnything/qanything_kernel/dependent_server/rerank_server && ln -s /root/models/linux_onnx/rerank_model_configs_v0.0.1 . fi if [ ! -L "/workspace/QAnything/qanything_kernel/dependent_server/ocr_server/ocr_models" ]; then # 如果不存在软连接 cd /workspace/QAnything/qanything_kernel/dependent_server/ocr_server && ln -s /root/models/ocr_models . # 创建软连接 fi if [ ! -L "/workspace/QAnything/qanything_kernel/dependent_server/pdf_parser_server/pdf_to_markdown/checkpoints" ]; then # 如果不存在软连接 cd /workspace/QAnything/qanything_kernel/dependent_server/pdf_parser_server/pdf_to_markdown/ && ln -s /root/models/pdf_models checkpoints # 创建软连接 fi if [ ! -L "/workspace/QAnything/nltk_data" ]; then # 如果不存在软连接 cd /workspace/QAnything/ && ln -s /root/nltk_data . # 创建软连接 fi从脚本内容结合官方README可知,models文件夹中要准备embedding、rerank、ocr、pdf四个模型,nltk_data下要准备nltk 数据model文件夹下要准备的数据下面下载模型数据都是在QAnything目录下执行安装modelscopepip install modelscopebce-embedding-base_v1modelscope download --model netease-youdao/bce-embedding-base_v1 --local_dir ./models/linux_onnx/embedding_model_configs_v0.0.1bce-reranker-base_v1modelscope download --model netease-youdao/bce-reranker-base_v1 --local_dir ./models/linux_onnx/rerank_model_configs_v0.0.1pdf_models和ocr_modelmodelscope download --model netease-youdao/QAnything-pdf-parser --local_dir ./models/pdf_modelspdf_models中已经包含了ocr,可以重用,这里要改下entrypoint.sh中ocr_models路径if [ ! -L "/workspace/QAnything/qanything_kernel/dependent_server/ocr_server/ocr_models" ]; then # 如果不存在软连接 cd /workspace/QAnything/qanything_kernel/dependent_server/ocr_server && ln -s /root/models/pdf_models/ocr ocr_models # 创建软连接 finltk_data文件夹下要准备的数据modelscope download --dataset CaiJichang/nltk_data --local_dir ./nltk_data构建之前需要对项目中的一些文件做些优化。Dockfile优化在QAnything目录下创建新的Dockerfilevi Dockerfile # 添加以下内容 # 使用官方 Python 3.10.14 镜像作为基础镜像 FROM python:3.10-slim # 替换APT源 RUN sed -i 's/http:\/\/deb.debian.org\//https:\/\/mirrors.huaweicloud.com\//g' /etc/apt/sources.list.d/debian.sources # 设置时区 ENV TZ=Asia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone # 安装 RUN apt-get update && apt-get install -y \ vim \ wget \ htop \ build-essential \ procps \ && rm -rf /var/lib/apt/lists/\* # 创建TikToken缓存目录 RUN mkdir /opt/tiktoken_cache # 下载TikToken模型缓存 ARG TIKTOKEN_URL="https://openaipublic.blob.core.windows.net/encodings/cl100k_base.tiktoken" RUN wget -O /opt/tiktoken_cache/$(echo -n $TIKTOKEN_URL | sha1sum | head -c 40) "$TIKTOKEN_URL" # 设置环境变量指向TikToken缓存目录 ENV TIKTOKEN_CACHE_DIR=/opt/tiktoken_cache # 复制 requirements.txt 文件到容器中 COPY requirements.txt /tmp/requirements.txt RUN pip config set global.index-url https://repo.huaweicloud.com/repository/pypi/simple \ && python -m pip install --upgrade pip # 安装 Python 依赖(torch单独安装CPU版本) RUN pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu \ && pip install -r /tmp/requirements.txt # 复制 models 文件夹到 /root 目录 COPY models /root/models COPY nltk_data /root/nltk_data # 设置工作目录 WORKDIR /workspace # 清理 APT 缓存 RUN apt-get clean && rm -rf /var/lib/apt/lists/\* # 设置默认命令 CMD ["/bin/bash"] requirements.txt优化默认的依赖包中会安装CUDA依赖,本次我们是纯CPU部署,不需要这些。vi requirements.txt # 添加以下内容 onnxruntime==1.17.1 xgboost-cpu==3.0.0 concurrent-log-handler==0.9.25 boto3==1.34.79 sanic==23.6.0 sanic_ext==23.6.0 langchain-openai==0.3.7 langchain_elasticsearch==0.3.2 langchain-community==0.3.18 unstructured==0.12.4 unstructured[pptx]==0.12.4 unstructured[md]==0.12.4 opencv-python-headless==4.9.0.80 python-dotenv==1.0.1 mysql-connector-python==8.2.0 pymilvus==2.5.5 aiomysql==0.2.0 PyMuPDF==1.24.4 openpyxl==3.1.2 python-docx==1.1.0 newspaper4k==0.9.3.1 newspaper4k[zh]==0.9.3.1 duckduckgo-search==5.3.0b4 html2text==2024.2.26 mistune==3.0.2 flair==0.13.0 nltk==3.8.1 pandas==2.1.1 scikit-learn==1.3.2 chardet==5.2.0 scipy==1.10.1 fastchat==0.1.0 wikipedia==1.4.0 Wikipedia-API==0.6.0 rouge-score==0.1.2 toml==0.10.2 tqdm==4.66.1 anthropic==0.25.7 streamlit==1.34.0 zhipuai==2.0.1.20240429 tiktoken==0.7.0 modelscope==1.13.0 cryptography==42.0.8 shapely==2.0.4 pyclipper==1.3.0.post5 pdfplumber==0.11.0 markdownify==0.12.1 datrie==0.8.2 hanziconv==0.3.2 PyPDF2==3.0.1 lxml_html_clean==0.1.1 docx2txt==0.8 构建docker镜像# 在QAnything目录下执行 docker build -t xixihahaliu01/qanything-linux:v1.5.1 . docker-compose-linux.yaml优化在qanything_local下的volumes,其实不用把整个QAnything映射到容器中,只需要映射需要的文件即可 volumes: - ${DOCKER_VOLUME_DIRECTORY:-.}/qanything_kernel:/workspace/QAnything/qanything_kernel - ${DOCKER_VOLUME_DIRECTORY:-.}/logs:/workspace/QAnything/logs - ${DOCKER_VOLUME_DIRECTORY:-.}/volumes:/workspace/QAnything/volumes - ${DOCKER_VOLUME_DIRECTORY:-.}/QANY_DB:/workspace/QAnything/QANY_DB - ${DOCKER_VOLUME_DIRECTORY:-.}/scripts/entrypoint.sh:/workspace/QAnything/scripts/entrypoint.sh代码优化qanything_kernel/core/retriever/vectorstore.py@get_time def delete_expr(self, expr): # 如果expr为空,则不执行删除操作 result = self.get_local_chunks(expr) if result is None or len(result) == 0: debug_logger.info(f'expr: {expr} not found in local milvus') return qanything_kernel/dependent_server/embedding_server/embedding_server.py 和 qanything_kernel/dependent_server/rerank_server/rerank_server.py增加以下代码from sanic.worker.manager import WorkerManager WorkerManager.THRESHOLD = 600 qanything_kernel/configs/model_config.py增加以下配置DEFAULT_PROMPT_TEMPLATE = """ 参考信息: {{context}} --- 我的问题或指令: {{question}} --- 请根据上述参考信息回答我的问题或回复我的指令。前面的参考信息可能有用,也可能没用,你需要从我给出的参考信息中选出与我的问题最相关的那些,来为你的回答提供依据。回答一定要忠于原文,简洁但不丢信息,不要胡乱编造。我的问题或指令是什么语种,你就用什么语种回复,你的回复: """ # 匹配后单段上下文长度 CHUNK_SIZE = 800 修改以下配置# 知识库检索时返回的匹配内容条数 VECTOR_SEARCH_TOP_K = 5 # embedding检索的相似度阈值,归一化后的L2距离,设置越大,召回越多,设置越小,召回越少 VECTOR_SEARCH_SCORE_THRESHOLD = 0.5 qanything_kernel/core/local_doc_qa.py # 在下面语句后增加 DEFAULT_PROMPT_TEMPLATE from qanything_kernel.configs.model_config import DEFAULT_PROMPT_TEMPLATE # 586~592做以下修改 if custom_prompt: # prompt_template = CUSTOM_PROMPT_TEMPLATE.replace("{{custom_prompt}}", custom_prompt) prompt_template = custom_prompt else: # system_prompt = SYSTEM.replace("{{today_date}}", today).replace("{{current_time}}", now) # prompt_template = PROMPT_TEMPLATE.replace("{{system}}", system_prompt).replace("{{instructions}}",INSTRUCTIONS) prompt_template = DEFAULT_PROMPT_TEMPLATE 启动项目run.sh 修改# 修改run.sh 93行 source ./.env启动# 在QAnything目录下执行 bash run.sh出现以下信息表示启动成功了访问项目在运行run.sh过程中会询问是在本地部署还是云服务上部署,如果是云服务器部署,就填入弹性IP的地址即可。体验项目新建知识库上传文档目前支持文件格式md、txt、pdf、jpg、png、jpeg、docx、xlsx、pptx、eml、csv, 单个文档小于30M, 单张图片小于5M, 文件总大小不得超过125M.文档越大,处理时间越长.备注中可以看大部分时间都耗费在embedding中,如果文档太大也可能会超时导致失败.预览切片结果PDF文件的解析原理是将其转换成Markedown文件,这可以最大限度保证原版的样式和内容.可以对照源文件对比查看,支持编辑修改.配置LLM大模型这里使用华为云ModelArts Studio大模型服务来作为LLM的提供商进入产品官网ModelArts Studio在API Key管理菜单项中申请一个Api Key进入在线推理菜单项,领取大模型服务免费额度进入对应服务的调用说明获取调用参数配置模型提供商问答会话接下来就可以进行问答会话了,这里用的是外部LLM服务,响应还是非常快的.
-
some tests failed.first verdict: runtime error请问一下能否给一些样例数据呢?只用example的数据运行检查不出来问题在哪里。或者是否能够开放日志下载呢?
-
请问这个报错是什么问题呢
-
大家好哦 ,三月份的干货合集来了,这次包含又redis,MySQL,HarmonyOS,Linux,Python,GoLang,Nginx,spring等多方面内容,希望可以帮到大家1.Redis Key的数量上限及优化策略分享【转】https://bbs.huaweicloud.com/forum/thread-02127178647758557099-1-1.html2.MySQL多列IN查询的实现【转】https://bbs.huaweicloud.com/forum/thread-0282178647688443077-1-1.html3.MySQL新增字段后Java实体未更新的潜在问题与解决方案【转】https://bbs.huaweicloud.com/forum/thread-0211178647622373117-1-1.html4.浅谈mysql的sql_mode可能会限制你的查询【转】https://bbs.huaweicloud.com/forum/thread-02127178647532278098-1-1.html5.MySQL使用SHOW PROCESSLIST的实现【转】https://bbs.huaweicloud.com/forum/thread-0238178647442172080-1-1.html6.HarmonyOS Next音乐播放器技术栈详解【转】https://bbs.huaweicloud.com/forum/thread-0213178647328545104-1-1.html7.Linux上设置Ollama服务配置(常用环境变量)【转】https://bbs.huaweicloud.com/forum/thread-0274178647201397098-1-1.html8.GORM中Model和Table的区别及使用【转】https://bbs.huaweicloud.com/forum/thread-0238178647121910079-1-1.html9. Python 的 ultralytics 库功能及安装方法【转】https://bbs.huaweicloud.com/forum/thread-0211178647036676116-1-1.html10.Python如何在Word中查找并替换文本【转】https://bbs.huaweicloud.com/forum/thread-0213178646924252103-1-1.html?fid=56811.GoLand 中设置默认项目文件夹的实现【转】https://bbs.huaweicloud.com/forum/thread-0210178646835711094-1-1.html12.Python Geopy库地理编码和地理距离计算案例展示【转】https://bbs.huaweicloud.com/forum/thread-0282178646750927076-1-1.html13.Java RMI技术详解与案例分析https://bbs.huaweicloud.com/forum/thread-0274178534386630091-1-1.html14.Volatile不保证原子性及解决方案https://bbs.huaweicloud.com/forum/thread-0274178534309336090-1-1.html15.Redis数据结构—跳跃表 skiplist 实现源码分析https://bbs.huaweicloud.com/forum/thread-0282178533434493072-1-1.html16.Java Executors类的9种创建线程池的方法及应用场景分析https://bbs.huaweicloud.com/forum/thread-0210178533186291086-1-1.html17.Nginx性能调优5招35式不可不知的策略实战https://bbs.huaweicloud.com/forum/thread-0213178533127218096-1-1.html18.Tomcat的配置文件中有哪些关键的配置项,它们分别有什么作用?https://bbs.huaweicloud.com/forum/thread-0210178533048188084-1-1.html19.深度长文解析SpringWebFlux响应式框架15个核心组件源码 https://bbs.huaweicloud.com/forum/thread-0282178532893901071-1-1.html20.对比传统数据库,TiDB 强在哪?谈谈 TiDB 的适应场景和产品能力https://bbs.huaweicloud.com/forum/thread-02127178532544750088-1-1.html
-
ultralytics 是一个专注于计算机视觉任务的 Python 库,尤其以 YOLO(You Only Look Once) 系列模型为核心,提供了简单易用的接口,支持目标检测、实例分割、姿态估计等任务。本文将详细介绍 ultralytics 库的功能、安装方法、核心模块以及使用示例。1. ultralytics 库简介ultralytics 库由 Ultralytics 团队开发,旨在为 YOLO 系列模型提供高效、灵活且易于使用的工具。它支持 YOLOv5、YOLOv8 等最新版本的 YOLO 模型,并提供了以下核心功能:目标检测:检测图像或视频中的目标。实例分割:对目标进行像素级分割。姿态估计:检测目标的关键点(如人体姿态)。模型训练:支持自定义数据集的训练。模型导出:将模型导出为多种格式(如 ONNX、TensorRT 等)。2. 安装 ultralyticsultralytics 可以通过 pip 安装:1pip install ultralytics安装完成后,可以通过以下命令验证是否安装成功:12import ultralyticsprint(ultralytics.__version__)3. 核心模块与功能(1)YOLO 模型加载与推理ultralytics 提供了 YOLO 类,用于加载预训练模型或自定义模型,并进行推理。加载模型123from ultralytics import YOLO# 加载预训练模型model = YOLO("yolov8n.pt") # YOLOv8 Nano 模型推理1234# 对单张图像进行推理results = model("image.jpg")# 显示结果results.show()保存结果12# 保存检测结果results.save("output.jpg")(2)模型训练ultralytics 支持自定义数据集的训练。准备数据集数据集需要按照 YOLO 格式组织:1234567dataset/├── images/│ ├── train/│ └── val/└── labels/ ├── train/ └── val/训练模型1234# 加载模型model = YOLO("yolov8n.pt")# 训练模型results = model.train(data="coco128.yaml", epochs=50, imgsz=640)(3)模型验证训练完成后,可以使用验证集评估模型性能。123# 验证模型metrics = model.val()print(metrics.box.map) # 打印 mAP 值(4)模型导出ultralytics 支持将模型导出为多种格式,以便在其他平台上部署。12# 导出为 ONNX 格式model.export(format="onnx")4. 使用示例目标检测1234567from ultralytics import YOLO# 加载模型model = YOLO("yolov8n.pt")# 对图像进行推理results = model("image.jpg")# 显示结果results.show()实例分割1234567from ultralytics import YOLO# 加载实例分割模型model = YOLO("yolov8n-seg.pt")# 对图像进行推理results = model("image.jpg")# 显示分割结果results.show()姿态估计1234567from ultralytics import YOLO# 加载姿态估计模型model = YOLO("yolov8n-pose.pt")# 对图像进行推理results = model("image.jpg")# 显示姿态估计结果results.show()视频推理1234567from ultralytics import YOLO# 加载模型model = YOLO("yolov8n.pt")# 对视频进行推理results = model("video.mp4")# 保存结果results.save("output.mp4")5. 高级功能(1)自定义模型ultralytics 支持加载自定义训练的模型。12345from ultralytics import YOLO# 加载自定义模型model = YOLO("custom_model.pt")# 推理results = model("image.jpg")(2)多 GPU 训练ultralytics 支持多 GPU 训练,以加速训练过程。12# 使用 4 个 GPU 进行训练results = model.train(data="coco128.yaml", epochs=50, imgsz=640, device=[0, 1, 2, 3])(3)TensorRT 加速ultralytics 支持将模型导出为 TensorRT 格式,以在 NVIDIA GPU 上加速推理。12# 导出为 TensorRT 格式model.export(format="engine")6. 总结ultralytics 是一个功能强大且易于使用的计算机视觉库,特别适合 YOLO 系列模型的应用。它提供了从模型加载、推理、训练到导出的完整功能,支持目标检测、实例分割、姿态估计等多种任务。无论是研究还是生产环境,ultralytics 都能满足你的需求。
-
在操作Word文档时,如果想要修正一处反复出现的拼写错误,统一文中前后不一致的术语,或者将文档中所有的旧联系方式更新为新号码。这时我们可以使用 Word中的查找替换功能,快速定位并批量处理文档中的特定文本,提升编辑效率。本文将通过以下几个示例介绍如何使用Python在Word中查找指定文本并替换。要实现通过Python操作Word文档,我们需要安装 Spire.Doc for Python 库。其pip安装命令如下:1pip install Spire.DocPython 查找并替换所有指定文本Spire.Doc for Python 库提供的 Document.Replace() 方法,可以查找Word 文档中的指定文本然后将所有匹配项直接替换为新的文本。示例代码如下:12345678910111213from spire.doc import *from spire.doc.common import * # 加载 Word 文档document = Document()document.LoadFromFile("实验.docx") # 查找指定文本并替换为新文本document.Replace("实验", "研究", False, True) # 保存结果文档document.SaveToFile("查找并替换文本.docx", FileFormat.Docx2016)document.Close()如果仅需替换第一个匹配的文本,可以在替换前将 Document.ReplaceFirst 属性设置为 True。1234# 仅替换第一个查找到的文本document.ReplaceFirst = True# 查找指定文本并将第一个匹配项替换为新文本document.Replace("实验", "研究", False, True)Python 使用正则表达式查找并替换文本正则表达式提供了丰富的元字符和操作符,可以根据不同的业务规则灵活调整匹配条件,满足各种复杂的替换需求。除了普通替换外,你也可以创建一个正则表达式,然后将其作为作为参数传递给 Document.Replace() 方法来替换。示例代码如下:12345678910111213141516from spire.doc import *from spire.doc.common import * # 加载 Word 文档document = Document()document.LoadFromFile("南极洲.docx") # 创建一个正则表达式来匹配整数或者小数regex = Regex(r'[0-9]+.{0,1}[0-9]{0,2}') # 查找匹配文本并替换document.Replace(regex, "xxxx") # 保存文档document.SaveToFile("正则表达式查找替换.docx", FileFormat.Docx2016)document.Close() Python 查找文本并用图片替换文本用图片替换文本的实现思路是:先查找指定文本,然后在查找到的文本位置处插入图片,最后再删除查找到的文本。步骤如下:1.使用 LoadFromFile() 方法加载 Word 文档。2.使用 FindAllString() 方法查找文档中的所有指定文本。3.遍历每一个查找到的结果,然后:使用 DocPicture.LoadImage() 方法加载图片;将查找到的文本转换为单个文本范围;获取文本范围在段落中的索引;通过 Insert() 方法在文本范围的索引位置处插入图片;通过 Remove() 方法删除段落中的文本。4.使用 SaveToFile() 方法保存生成的文档。
上滑加载中
推荐直播
-
华为云码道Agent集成与鸿蒙实战2026/08/11 周二 19:00-21:00
王一男-华为云码道产品规划专家;李炎-华为云码道产品专家;彭江敏-华为云鸿蒙端云一体化开发专家
本次直播带你解读华为云码道7月份产品新特性、新功能。更有专家演示码道Agent Space × 钉钉机器集成实战,从0到1打通消息通道;码道鸿蒙端云一体化实战,快速搭建员工签到系统。
回顾中 -
华为云开发者AI素养直播课·第五期2026/09/04 周五 16:00-18:00
林华鼎-华为云AI开发者运营负责人;蒋春阳-华为云AI开发者案例开发专家
本期直播内容: AI工具体验营 · 第5-8课连讲。Agent-Team 多智能体协作完成毕业设计实践
回顾中 -
华为云开发者AI素养ClassRoom·第六期2026/09/08 周二 19:00-20:00
樊渊-2026华为软件挑战赛冠军
高手来了:看软挑高手解析二维排样问题—从工业难题到算法突破
回顾中
热门标签