博客

  • py获取文件后缀

    推荐使用os.path.splitext(file_path),因为这个能够直接获得后缀名,若是自己分割的话,需要考虑文件名中是否有多个.符号

    kimi ai

    在Python中,获取文件的后缀名(扩展名)通常涉及到对文件名进行字符串操作。一个常见的方法是使用os.path.splitext()函数,它能够分割文件名和扩展名。以下是一些获取文件后缀的基本方法:

    使用os.path.splitext()

    import os

    # 假设有一个文件路径
    file_path = 'example.txt'

    # 使用os.path.splitext()获取文件后缀
    _, file_extension = os.path.splitext(file_path)

    print(file_extension) # 输出: .txt

    os.path.splitext()函数返回一个元组,其中第一个元素是文件名(不包含扩展名),第二个元素是文件的扩展名。

    使用字符串方法

    如果你不想使用os.path.splitext(),也可以通过字符串方法来获取文件后缀:

    # 假设有一个文件路径
    file_path = 'example.txt'

    # 字符串方法获取文件后缀
    file_extension = file_path.split('.')[-1] if '.' in file_path else ''

    print(file_extension) # 输出: txt

    这种方法首先检查文件名中是否有.,如果有,就使用split()方法分割字符串,并取最后一个元素作为扩展名。

    使用pathlib模块

    从Python 3.4开始,pathlib模块提供了面向对象的文件系统路径操作方法,也可以方便地获取文件扩展名:

    from pathlib import Path

    # 假设有一个文件路径
    file_path = Path('example.txt')

    # 使用pathlib获取文件后缀
    file_extension = file_path.suffix

    print(file_extension) # 输出: .txt

    Path.suffix属性直接返回文件的扩展名,包括点(.)。

    注意事项

    • 如果文件名中包含多个点,os.path.splitext()pathlib.suffix只会返回最后一个点之后的部分作为扩展名。
    • 如果文件名没有点,os.path.splitext()会返回空字符串,而pathlib.suffix会返回一个空字符串。

    选择哪种方法取决于你的具体需求和Python版本。

  • for /L %i IN (1,1,254) DO ping -w 1 -n 1 192.168.3.%i

    https://jingyan.baidu.com/article/3d69c551251054b1ce02d73e.html

     

    for /L %i IN (1,1,254) DO ping -w 1 -n 1 192.168.3.%i

    以上cmd命令可以ping测试192.168.10网段下的所有ip地址

    也可以把ping -w 1的1改为0.001,这样请求结果会更快

    然后通过arp -a命令查看缓存表有哪些ip地址在线

     

    kimi ai

    这是一条Windows命令提示符(cmd)下的批处理命令,用于对一个指定的子网中的所有可能的IP地址进行ping操作。具体来说,这条命令会尝试ping网段 192.168.3.0192.168.3.255 中的每一个IP地址。下面是命令各部分的详细解释:

    • for /L %i IN (1,1,254):这是一个for循环,/L表示循环变量 %i 将是一个数值。括号中的三个数字分别代表起始值(1)、步长(1)、结束值(254)。这个循环将从1开始,每次增加1,直到254结束。
    • DO:表示对于循环中的每个值,都执行后面的命令。
    • ping:这是Windows系统中用于发送ICMP回显请求的命令,用来检查网络连接是否可达。
    • -w 1-w 参数后面跟的数字表示等待响应的时间,单位是秒。这里设置为1秒,意味着每个ping请求发送后,等待1秒来接收响应。
    • -n 1-n 参数后面跟的数字表示发送的ping请求的次数。这里设置为1,意味着对每个IP地址只发送一次请求。
    • 192.168.3.%i:这是ping命令的目标IP地址。%i 会被循环中的当前数值所替换,因此实际的命令会是 ping -w 1 -n 1 192.168.3.1,然后是 192.168.3.2,依此类推,直到 192.168.3.254

    整个命令的作用是遍历子网 192.168.3.x 中的每个IP地址,发送单个ping请求,以检查哪些设备在线并响应ping。这可以用于快速扫描局域网内的活动设备。

    请注意,这个命令在某些网络环境中可能不被允许,因为它可能会产生大量网络流量,或者被网络管理员视为不安全的行为。此外,一些设备可能由于配置或策略原因,不会响应ping请求。

    kimi ai

    arp -a 是一个在 Windows 命令提示符(cmd)中使用的命令,用于显示当前的ARP(地址解析协议)缓存表。ARP缓存表存储了IP地址到MAC地址的映射关系,这些信息用于在本地网络(局域网)中解析和转发数据包。

    当网络中的设备需要通信时,它们使用ARP来查询其他设备的MAC地址。一旦查询到,该映射关系会被缓存一段时间,以避免重复查询。

    以下是 arp -a 命令的一些关键点:

    • 显示所有ARP条目arp -a 显示当前缓存中的所有ARP条目,包括静态和动态条目。
    • 接口:如果计算机连接到多个网络接口,arp -a 会为每个接口显示ARP缓存。
    • 条目信息:每个条目通常包括IP地址、MAC地址、类型(动态或静态)以及该条目最后被使用的时间。
    • 动态与静态条目:动态条目是自动添加的,当网络通信发生时,而静态条目是手动添加的,用于永久映射特定的IP地址到MAC地址。

    使用示例

    打开命令提示符,然后输入以下命令:

    arp -a

    这将列出所有当前的ARP缓存条目。

    其他ARP命令

    除了 arp -a,还有一些相关的命令用于管理ARP缓存:

    • arp -d:删除指定的ARP缓存条目。
    • arp -s:手动添加静态ARP缓存条目。

    例如,要删除指定的ARP缓存条目,可以使用:

    arp -d IP_ADDRESS

    IP_ADDRESS 替换为要删除的IP地址。

    要添加静态ARP条目,可以使用:

    arp -s IP_ADDRESS MAC_ADDRESS

    IP_ADDRESS 替换为要添加的IP地址,将 MAC_ADDRESS 替换为对应的MAC地址。

    使用这些命令可以帮助你管理网络配置和解决网络问题。

  • flask分页

    <div class="pagination">
      {% if pagination.has_prev %}
          <a href="{{ url_for('search.do_search', page=pagination.prev_num, search=query) }}">上一页</a>
      {% endif %}
      &nbsp;&nbsp;&nbsp;&nbsp;
      {% for page in pagination.iter_pages() %}
          {% if page %}
              {% if page == pagination.page %}
                  <span>{{ page }}</span>
                  &nbsp;&nbsp;&nbsp;&nbsp;
              {% else %}
                  <a href="{{ url_for('search.do_search', page=page, search=query) }}">{{ page }}</a>
                  &nbsp;&nbsp;&nbsp;&nbsp;
              {% endif %}
          {% endif %}
      {% endfor %}
    
      {% if pagination.has_next %}
          <a href="{{ url_for('search.do_search', page=pagination.next_num, search=query) }}">下一页</a>
      {% endif %}
    </div>

     

    kimi ai

    这段代码是一个分页导航的 HTML 模板片段,通常用在 Web 应用中,以便用户可以浏览不同的数据页。它使用了 Flask 的 pagination 对象,这个对象是通过查询集的 paginate 方法生成的。这里使用的是 Jinja2 模板语言,这是 Flask 推荐使用的模板引擎。下面是代码的详细解释:

    1. 分页容器<div class="pagination"> 创建了一个包含所有分页链接的容器,并使用 pagination 类来应用 Bootstrap 的分页样式(假设你正在使用 Bootstrap)。
    2. 上一页链接{% if pagination.has_prev %} 检查是否存在上一页。
      • 如果有上一页,<a href="{{ url_for('search.do_search', page=pagination.prev_num, search=query) }}">上一页</a> 生成一个链接到上一页。url_for 函数用于生成 URL,其中 'search.do_search' 是视图函数的端点名称,page=pagination.prev_num 指定了上一页的页码,search=query 保留了当前搜索查询的参数。
    3. 分页数字{% for page in pagination.iter_pages() %} 循环遍历所有可点击的页码。
      • {% if page %} 确保页码是有效的(非空,非 None)。
      • {% if page == pagination.page %} 检查当前页码,并将其高亮显示(在这里,只是简单地用 <span> 包裹,而不是 <a>)。
      • 如果页码不是当前页,生成一个链接到该页码的 <a> 元素。
      • &nbsp;&nbsp;&nbsp;&nbsp; 表示非断行空格,用于在链接之间添加空间。
    4. 下一页链接{% if pagination.has_next %} 检查是否存在下一页。
      • 如果有下一页,<a href="{{ url_for('search.do_search', page=pagination.next_num, search=query) }}">下一页</a> 生成一个链接到下一页。

    模板变量解释:

    • pagination:由 Flask-SQLAlchemy 的 paginate 方法返回的分页对象,包含了分页信息和方法。
    • pagination.has_prev:布尔值,表示是否有上一页。
    • pagination.prev_num:上一页的页码。
    • pagination.page:当前页码。
    • pagination.iter_pages():生成一个迭代器,包含所有可显示的页码。
    • pagination.has_next:布尔值,表示是否有下一页。
    • pagination.next_num:下一页的页码。

    注意事项:

    • 确保 search 查询参数是从某处获取的,可能是通过 request.args.get('search')
    • url_for 需要与你的路由名称匹配,确保 'search.do_search' 是正确的视图函数名称。
    • 分页导航的样式可以通过 CSS 进一步定制。
    • 如果分页导航没有按预期工作,检查 paginate 方法的调用是否正确,以及 query 参数是否正确传递到视图函数中。

    这段代码是动态生成的,依赖于后端提供的数据和当前用户的请求参数。

  • 使用pywin32库,例如,可以访问Windows的COM接口,如IShellDispatch,来获取文件系统信息

    kimi ai

    使用 pywin32 库来访问 Windows 的 COM 接口,如 IShellDispatch,可以提供一种方法来与 Windows Shell 交互,从而获取文件系统信息。以下是如何使用 pywin32 来实现这一目的的基本步骤:

    1. 安装 pywin32: 首先,确保你已经安装了 pywin32。如果还没有安装,可以通过 pip 安装:
      pip install pywin32
    2. 使用 IShellDispatch 接口IShellDispatch 是 Windows Shell 应用程序接口的一部分,可以用来获取文件和文件夹的信息。
    import win32com.client
    
    # 创建一个 Shell 应用程序的实例
    shell = win32com.client.Dispatch("Shell.Application")
    
    # 获取系统盘的 Folder 项
    system_drive = shell.NameSpace("C:\\")
    
    # 遍历系统盘下的所有项
    for item in system_drive.Items():
        print(f"Name: {item.Name}")
        print(f"Path: {item.Path}")
        print(f"Type: {item.Type}")
        print(f"IsFolder: {item.IsFolder}")
        print("-----")

    输出内容如下(部分):

    Name: application
    Path: C:\application
    Type: 文件夹
    IsFolder: True
    -----
    Name: FPA_OS
    Path: C:\FPA_OS
    Type: 文件夹
    IsFolder: True
    -----
    Name: Genshin Impact Game
    Path: C:\Genshin Impact Game
    Type: 文件夹
    IsFolder: True

     

  • 有什么办法能够让大文件hash快一点吗

    kimi ai

    计算大文件的哈希值时,性能可能会受到文件读取速度和哈希计算速度的影响。以下是一些优化大文件哈希计算速度的方法:

    1. 增加读取块大小:在您的代码中,每次读取文件的块大小是4096字节。您可以尝试增加这个块大小,以减少读取次数。但是要注意不要设置得太大,以免占用过多内存。
    2. 多线程或多进程:如果文件非常大,可以考虑使用多线程或多进程来并行处理文件的不同部分。Python的concurrent.futures模块可以用来实现这一点。
    3. 使用更快的哈希算法:虽然SHA-256是一个广泛使用的算法,但如果您对安全性要求不高,可以考虑使用更快的哈希算法,比如MD5或SHA-1。但请注意,这些算法不再推荐用于需要高安全性的场景。
    4. 优化I/O操作:确保文件系统和存储设备的性能是最优的。例如,使用SSD而不是HDD可以显著提高I/O速度。
    5. 减少日志记录:在处理大文件时,减少或优化日志记录操作,因为日志记录可能会降低性能。
    6. 使用更快的硬件:如果可能的话,使用更快的CPU和更多的RAM可以提高哈希计算的速度。
    7. 避免使用Python的GIL:Python的全局解释器锁(GIL)可能会限制多线程的并行执行。在某些情况下,使用多进程而不是多线程可能会获得更好的性能。
    8. 使用专门的库:有些专门的库可能对哈希计算进行了优化,比如hashlib的某些实现可能比其他实现更快。
    9. 预分配内存:如果使用文件读取函数,预分配足够的内存空间可以减少内存分配的开销。
    10. 避免在循环中打印日志或输出:在循环中打印日志或输出到控制台会显著降低性能,应该尽量避免。

    请注意,即使采取了上述措施,哈希计算仍然是一个计算密集型的任务,特别是对于非常大的文件。您需要在安全性、性能和资源使用之间找到平衡点。

  • #!/usr/bin/python什么意思

    #!/usr/bin/python 是一个称为 shebang 或 hashbang 的特殊行,它通常出现在 Unix 和类 Unix 系统的脚本文件的开头。这个行告诉操作系统,这个脚本应该使用哪个解释器来执行。具体来说,#!/usr/bin/python 表示脚本应该使用位于 /usr/bin/python 路径的 Python 解释器来运行。

    这里是它的一些要点:

    • #!:这个符号叫做 shebang 或 hashbang,是脚本的开始标记。
    • /usr/bin/python:这是 Python 解释器的路径。在不同的系统或环境中,Python 解释器的路径可能不同。

    当你在一个脚本文件的顶部添加了 shebang 行,并且给脚本文件赋予了执行权限(例如,使用 chmod +x script.py 命令),你就可以直接通过在命令行中调用这个脚本文件名来运行它,而不需要指定 Python 解释器的路径。例如:

    ./script.py

    这将执行脚本,就像调用 /usr/bin/python script.py 一样。

    需要注意的是,shebang 行在 Windows 系统中通常不被使用,因为 Windows 使用不同的机制来确定如何执行脚本。此外,如果你的 Python 解释器安装在不同的路径,你需要相应地修改 shebang 行中的路径。例如,如果你使用的是 Python 3,路径可能是 #!/usr/bin/python3

  • flask里面的app.secret_key这个值对于用户有什么影响吗?可以随机吗?

    kimi ai

    在Flask框架中,app.secret_key 是一个重要的配置项,它用于确保应用程序的安全性,尤其是在以下几个方面:

    1. 会话加密:Flask 使用 secret_key 来安全地签名客户端会话。如果攻击者能够预测 secret_key,他们可能会伪造会话,从而绕过身份验证。
    2. CSRF 保护:Flask-WTF 扩展使用 secret_key 来生成 CSRF 令牌,以防止跨站请求伪造攻击。
    3. 密码重置令牌:Flask-Login 等扩展可能使用 secret_key 来生成密码重置令牌,确保重置链接的安全性。
    4. 数据签名:Flask 允许你使用 secret_key 来创建签名的数据,这可以用于确保数据在传输过程中的完整性。
    5. 加密敏感数据:虽然不常见,但 secret_key 有时也用于加密敏感数据。

    对于用户来说,secret_key 的影响通常是间接的,因为它主要用于保护应用程序免受攻击,从而间接保护用户的安全和隐私。用户通常不需要直接与 secret_key 交互,但应该确保应用程序的 secret_key 是安全的,不被泄露给未经授权的人。

     

    如果你正在开发一个 Flask 应用程序,你应该设置一个难以猜测的 secret_key 值,并且不要在公共代码库中暴露它。在生产环境中,你应该使用环境变量或配置文件来安全地存储 secret_key

    app.secret_key 设置为一个完全随机的值是一个非常好的安全实践。以下是一些原因和建议:

    1. 增强安全性:随机生成的 secret_key 难以预测,这增加了破解会话和CSRF令牌的难度。
    2. 防止会话劫持:如果 secret_key 是公开的或容易被猜到的,攻击者可以伪造会话令牌,从而可能劫持用户的会话。
    3. CSRF 保护:随机的 secret_key 有助于生成难以预测的CSRF令牌,从而减少跨站请求伪造攻击的风险。
    4. 密码重置和数据签名:随机的 secret_key 也有助于确保密码重置链接和签名数据的安全性。
    5. 避免硬编码:避免在代码中硬编码 secret_key,而是应该使用环境变量或配置文件来设置它。
    6. 定期更换:虽然随机生成的 secret_key 可以提供很好的安全性,但定期更换 secret_key 也是一个好习惯,特别是如果你怀疑它可能已经被泄露。
    7. 使用强随机数生成器:确保使用加密安全的随机数生成器来生成 secret_key,以避免使用可能不够安全的伪随机数生成器。

    在Flask中,你可以使用Python的 os.urandom() 函数来生成一个随机的密钥:

    python
    import os
    app.secret_key = os.urandom(24)

    这将生成一个24字节的随机密钥,足以满足大多数安全需求。记得将这个密钥保存在安全的地方,比如环境变量中,以避免在代码库中暴露它。

  • py文件hash

    import hashlib
    def 计算文件hash值(文件绝对路径):
        '''
        输出了64字节长度的字符
        关于hashlib详见:
        https://www.runoob.com/python3/python-hashlib.html
        '''
        hash_func = hashlib.sha256()
        try:
            with open(文件绝对路径, 'rb') as f:
                for chunk in iter(lambda: f.read(4096), b""):
                    hash_func.update(chunk)
            return hash_func.hexdigest()
        except IOError as e:  # 捕获文件读取错误
            flash('读取文件时发生IO错误:' + str(e))
            current_app.logger.warning('读取文件时发生IO错误:' + str(e))
            return None

     

    这段Python代码是一个用于计算文件SHA-256哈希值的函数。SHA-256是一种加密哈希函数,常用于验证文件的完整性。下面是这段代码的详细解释:

    1. hash_func = hashlib.sha256(): 这行代码初始化了一个SHA-256哈希对象。hashlib 是Python中用于哈希算法的库,sha256 是其中一种算法。
    2. try:: 这是一个异常处理的开始,try块中的代码将尝试执行,如果发生异常,将跳转到except块。
    3. with open(文件绝对路径, 'rb') as f:: 使用with语句打开一个文件,文件绝对路径需要替换成实际的文件路径。'rb'表示以二进制读取模式打开文件。as f将文件对象赋值给变量f
    4. for chunk in iter(lambda: f.read(4096), b""):: 这是一个循环,使用iter函数和lambda匿名函数创建一个迭代器,每次从文件中读取4096字节的数据(一个chunk),直到文件结束(即f.read(4096)返回空字节串b"")。
    5. hash_func.update(chunk): 将读取的文件块(chunk)的数据更新到哈希对象中。SHA-256算法是逐步处理数据的,所以需要在读取每个块后更新哈希状态。
    6. return hash_func.hexdigest(): 在循环结束后,返回哈希对象的十六进制摘要字符串。hexdigest方法将内部的哈希值转换为十六进制格式的字符串。
    7. except IOError as e:: 如果在尝试打开或读取文件时发生IO错误(例如文件不存在或权限问题),这行代码会捕获这个异常。
    8. flash('读取文件时发生IO错误:' + str(e)): 这行代码可能是用于Web应用中的一个函数,用于显示一个flash消息,告知用户发生了IO错误,并显示错误信息。
    9. current_app.logger.warning('读取文件时发生IO错误:' + str(e)): 这行代码记录了一个警告级别的日志,包含了发生的错误信息。current_app是一个Flask应用的引用,logger是其日志记录器。
    10. return None: 如果发生异常,函数将返回None,表示没有成功计算出哈希值。

    请注意,这段代码中有几个地方需要根据实际情况进行修改:

    • 文件绝对路径需要替换成实际的文件路径。
    • flashcurrent_app.logger的使用依赖于特定的Web框架(如Flask),如果你不是在Web应用中使用这段代码,可能需要替换或删除这些行。
  • ERROR: pip’s dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts. tensorflow-gpu 2.6.0 requires typing-extensions~=3.7.4, but you have typing-extensions 4.12.2 which is incompatible.

    ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
    tensorflow-gpu 2.6.0 requires typing-extensions~=3.7.4, but you have typing-extensions 4.12.2 which is incompatible.

    tensorflow-gpu卸载掉就行了

  • flask 日志使用

    Python 的 logging 模块中,%(filename)s 占位符用于在日志输出中包含记录日志消息的源文件的名称。如果你的日志输出显示的是“应用”或者不是预期的文件名,这可能是因为:

    1. Logger Name: %(name)s 占位符用于输出 Logger 的名字,而不是文件名。如果你想要输出文件名,确保你在日志格式中使用的是 %(filename)s
    2. Formatter 配置: 检查你的日志格式设置是否正确。确保你的 Formatter 对象使用了 %(filename)s 而不是 %(name)s
    3. Logger Name 和默认值: 如果你使用的是默认的 logger (root logger),它的名字是 'root'。如果你创建了自定义的 logger,它的名字会是你在创建时指定的。
    4. 日志调用位置: 确保你的日志调用位于你想要输出文件名的模块中。如果你在一个模块中调用日志,但日志配置在另一个模块中,可能不会显示正确的文件名。
    5. 多个 Handlers: 如果你为同一个 logger 添加了多个 handlers,确保所有 handlers 都使用了相同的 formatter。

    根据你提供的代码,你的日志格式字符串是:

    python
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

    这里使用的是 %(name)s,它将输出 logger 的名字而不是文件名。要显示文件名,你应该将格式字符串改为:

    python
    formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s')

    这样就会在日志输出中包含文件名和行号。

    另外,你的代码中创建了两个 handler,第一个是 TimedRotatingFileHandler,第二个是 FileHandler,并且第二个 handler 覆盖了第一个的设置。你应该只使用一个 handler 并确保它被添加到了 app.logger。以下是修正后的代码片段:

    # ...[省略其他导入和配置]...
    
    def create_app(config_class=Config):
        # 创建 Flask 应用
        app = Flask(__name__)
        app.config.from_object(config_class)
    
        # 创建并设置日志 handler
        handler = TimedRotatingFileHandler(
            "flask.log", when="D", interval=1, backupCount=15,
            encoding="utf-8", delay=False, utc=True
        )
        
        # 创建日志格式器并设置到 handler
        formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s')
        handler.setFormatter(formatter)
        
        # 将 handler 添加到 Flask app 的默认 logger
        app.logger.addHandler(handler)
        app.logger.setLevel(logging.INFO)  # 设置日志级别
    
        # ...[省略初始化 CKEditor、CSRFProtect、数据库和注册蓝图等]...
    
        return app

     

    确保你的应用中只使用一个 logger,并且所有的日志调用都使用这个 logger。这样,你的日志输出就会包含正确的文件名和行号。