普通视图

发现新文章,点击刷新页面。
昨天 — 2025年10月24日首页

深入Lua包(Package)与依赖管理

作者 烛阴
2025年10月24日 12:28

一、包的目录结构与require

require 函数天生就能理解目录结构。它通过点(.)来代表目录分隔符。

假设我们有这样一个项目结构:

/my_app
├── main.lua
└── /geometry       <-- 这是一个包
    ├── shape.lua
    └── transform.lua

shape.lua:

local M = {}
function M.new_circle(radius) return { type = 'circle', r = radius, x = 0, y = 0 } end
return M

transform.lua:

local M = {}
function M.move(shape, dx, dy)
    shape.x = shape.x + dx
    shape.y = shape.y + dy
    return shape
end
return M

main.lua 中,我们可以轻松地加载这个包里的模块:

-- main.lua

-- 加载 geometry 包中的 shape 模块
local Shape = require("geometry.shape")

-- 加载 geometry 包中的 transform 模块
local Transform = require("geometry.transform")

-- 现在可以使用它们的功能
local circle = Shape.new_circle(10)
local moved_circle = Transform.move(circle, 5, 5)

print("圆形位置:", moved_circle.x, moved_circle.y)

二、包的核心入口:init.lua 文件

当我们无法或者不需要理解包内部结构时,就需要 init.lua 来导出外部需要的接口。require 一个目录时,Lua 会自动寻找并加载该目录下的 init.lua 文件

让我们来改造一下上面的 geometry 包:

目录结构:

/my_app
├── main.lua
└── /geometry
    ├── shape.lua
    ├── transform.lua
    └── init.lua      <-- 新增的核心入口文件

init.lua (关键部分):

-- geometry/init.lua

-- 1. 创建一个代表整个包的表
local geometry = {}

-- 2. 加载包内部的私有模块
local Shape = require("geometry.shape")
local Transform = require("geometry.transform")

-- 3. 将需要暴露给外部的函数,挂载到 geometry 表上
geometry.create_circle = Shape.new_circle
geometry.move_shape = Transform.move

-- 4. 返回这个整合后的表
return geometry

现在,我们的 main.lua 可以变得更加简洁和高内聚:

-- main.lua

-- 只需要加载 geometry 这一个包!
local geometry = require("geometry")

-- 通过包提供的主接口来使用功能
local my_shape = geometry.create_circle(10)
geometry.move_shape(my_shape, 5, 5)

print("形状位置:", my_shape.x, my_shape.y)

三、包的搜索路径:package.path

当你调用 require("geometry") 时,Lua 怎么知道去哪里找这个文件呢?它使用 package.path 这个变量,其中包含一系列搜索路径模板。

你可以查看它:

print(package.path)

通常会输出类似这样的内容:

./?.lua;/usr/local/share/lua/5.4/?.lua;/usr/local/share/lua/5.4/?/init.lua

其中的 ? 会被你传给 require 的模块名替换。

如果需要,你也可以修改它来添加自定义搜索路径:

package.path = package.path .. ";/my/custom/path/?.lua"

结语

点个赞,关注我获取更多实用 Lua 技术干货!如果觉得有用,记得收藏本文!

昨天以前首页

用 Python 揭秘 IP 地址背后的地理位置和信息

作者 烛阴
2025年10月20日 22:13

准备工作:安装必备工具

首先,请确保你的Python环境中安装了requests库。

pip install requests

第一步:查询自己的公网 IP 信息

import requests
import json

# 向ipinfo.io发送请求,不带任何IP地址,它会默认查询你自己的IP
url = "https://ipinfo.io/json"

try:
    response = requests.get(url)
    response.raise_for_status() # 如果请求失败 (如状态码 4xx, 5xx), 会抛出异常

    # 将返回的JSON格式数据解析为Python字典
    data = response.json()

    print("--- 你的IP信息详情 ---")
    # 为了美观,使用json.dumps进行格式化输出
    print(json.dumps(data, indent=4, ensure_ascii=False))

except requests.exceptions.RequestException as e:
    print(f"请求失败: {e}")

运行后,你将看到类似这样的输出(信息会根据你的实际情况而变):

{
    "ip": "xxx.xxx.xxx.xxx",
    "hostname": "some.host.name",
    "city": "xx",
    "region": "xx",
    "country": "CN",
    "loc": "39.9042,116.4074",
    "org": "xx",
    "postal": "100000",
    "timezone": "Asia/Shanghai",
    "readme": "https://ipinfo.io/missingauth"
}

第二步:查询任意指定的 IP 地址

我们可以查询任何一个我们想查的公网IP,比如谷歌的公共DNS服务器 8.8.8.8

import requests
import json

# 定义要查询的IP地址
target_ip = "8.8.8.8"

# 构造请求URL,将IP地址拼接到URL中
url = f"https://ipinfo.io/{target_ip}/json"

try:
    response = requests.get(url)
    response.raise_for_status()

    data = response.json()

    print(f"--- IP: {target_ip} 的信息详情 ---")
    print(json.dumps(data, indent=4, ensure_ascii=False))

except requests.exceptions.RequestException as e:
    print(f"请求失败: {e}")

输出将会是:

{
    "ip": "8.8.8.8",
    "hostname": "dns.google",
    "city": "Mountain View",
    "region": "California",
    "country": "US",
    "loc": "37.4056,-122.0775",
    "org": "AS15169 Google LLC",
    "postal": "94043",
    "timezone": "America/Los_Angeles",
    "readme": "https://ipinfo.io/missingauth",
    "anycast": true
}

第三步:自由封装成自己需要的内容显示库

示例

import requests

def get_ip_info(ip_address: str) -> dict | None:
    """
    查询指定IP地址的详细信息。
    
    :param ip_address: 要查询的IP地址字符串。
    :return: 包含IP信息的字典,如果查询失败则返回None。
    """
    url = f"https://ipinfo.io/{ip_address}/json"
    try:
        response = requests.get(url, timeout=5) # 增加超时设置
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as e:
        print(f"查询IP {ip_address} 时出错: {e}")
        return None

# --- 使用我们封装好的函数 ---
if __name__ == "__main__":
    ip_list = ["8.8.8.8", "1.1.1.1", "114.114.114.114"]
    
    for ip in ip_list:
        info = get_ip_info(ip)
        if info:
            country = info.get('country', 'N/A')
            city = info.get('city', 'N/A')
            org = info.get('org', 'N/A')
            print(f"IP: {ip:<15} | Location: {country}, {city} | Organization: {org}")

结语

点个赞,关注我获取更多实用 Python 技术干货!如果觉得有用,记得收藏本文!

武装你的Python“工具箱”:盘点10个你必须熟练掌握的核心方法

作者 烛阴
2025年10月11日 22:47

一、字符串方法

字符串处理是我们日常编程中最高频的操作之一。

  1. .strip() - 去除首尾空白

    • 示例
      user_input = "  admin  \n"
      cleaned_input = user_input.strip()
      print(f"清理前: '{user_input}', 清理后: '{cleaned_input}'")
      # 输出: 
      #清理前: '  admin  
      #', 清理后: 'admin'
      
  2. .split() - 字符串切割

    • 示例
      csv_line = "apple,banana,orange,grape"
      fruits = csv_line.split(',')
      print(fruits)
      # 输出: ['apple', 'banana', 'orange', 'grape']
      
  3. .join() - 列表拼接成字符串

    • 示例
      words = ['Hello', 'Python', 'World']
      sentence = ' '.join(words)
      print(sentence)
      # 输出: Hello Python World
      
  4. f-string (格式化字符串)

    • 示例
      name = "张三"
      age = 30
      greeting = f"大家好,我叫{name},今年{age}岁了。"
      print(greeting)
      # 输出: 大家好,我叫张三,今年30岁了。
      

二、列表方法

列表是Python中使用最广泛的数据结构,下面这几个方法是管理列表内容的基础。

  1. .append() - 在末尾添加元素

    • 示例
      tasks = ['吃饭', '睡觉']
      tasks.append('写代码')
      print(tasks)
      # 输出: ['吃饭', '睡觉', '写代码']
      
  2. .sort() - 原地排序

    • 示例
      numbers = [3, 1, 4, 1, 5, 9, 2]
      numbers.sort(reverse=True) # reverse=True 表示降序
      print(numbers)
      # 输出: [9, 5, 4, 3, 2, 1, 1]
      

三、字典方法

字典通过键值对存储数据,访问速度极快。

  1. .get() - 安全地获取值

    • 示例
      user_info = {'name': 'Bob', 'age': 25}
      # 安全地获取职业,如果不存在,返回'未知'
      job = user_info.get('job', '未知')
      print(f"{user_info['name']}的职业是: {job}")
      # 输出: Bob的职业是: 未知
      
  2. .items() - 遍历键值对

    • 示例
      scores = {'数学': 95, '英语': 88, '科学': 92}
      for subject, score in scores.items():
          print(f"科目: {subject}, 分数: {score}")
      

四、通用内置函数

它们不属于某个特定类型,但功能强大,适用范围极广。

  1. len() - 获取长度

    • 示例
      print(len("Hello"))             # 5
      print(len([1, 2, 3, 4]))      # 4
      print(len({'a': 1, 'b': 2})) # 2
      
  2. range() - 生成数字序列

    • 示例
      # 打印 0 到 4
      for i in range(5):
          print(i, end=' ')
      # 输出: 0 1 2 3 4
      

结语

点个赞,关注我获取更多实用 Python 技术干货!如果觉得有用,记得收藏本文!

❌
❌