Python 变量的赋值与对象引用

诸如list的可变类型,变量赋值时原变量与新变量指向同一对象

1. 对象引用

在 Python 中,变量保存的不是对象本身,而是对对象的引用。赋值操作(例如 a = b)会复制引用,而不是创建新的对象。这意味着 ab 指向同一块内存中的对象,因此对可变对象的修改会在所有指向该对象的变量中生效。

   a = [1, 2, 3]
   b = a  # b 和 a 指向同一个对象
   b[0] = 99
   print(a)  # 输出: [99, 2, 3]

2. 可变和不可变类型

  • 不可变类型:包括 int(整数)、float(浮点数)、str(字符串)、tuple(元组)等。这些对象一旦创建,其内容就无法改变。每次尝试修改会创建一个新对象,而不会改变原有对象。
    python x = 10 y = x y = 20 print(x) # 输出: 10,不受 y 修改的影响
  • 可变类型:包括 list(列表)、dict(字典)、set(集合)等。这些对象可以直接修改其内容,不需要创建新对象,因此所有指向该对象的引用都会受到影响。

3. 浅拷贝与深拷贝

  • 浅拷贝:只复制对象的本身,但对于对象中的嵌套可变对象,仅复制其引用。也就是说,浅拷贝后的对象与原始对象共享内部嵌套对象。 import copy original = [[1, 2], [3, 4]] shallow_copy = copy.copy(original) shallow_copy[0][0] = 99 print(original) # 输出: [[99, 2], [3, 4]]
  • 深拷贝:复制对象及其所有嵌套对象,确保新对象完全独立于原始对象。深拷贝不会共享任何嵌套对象的引用。
    python deep_copy = copy.deepcopy(original) deep_copy[0][0] = 42 print(original) # 输出: [[99, 2], [3, 4]]

总结

  • 引用:Python 中变量是对象的引用,赋值是引用的复制。
  • 可变与不可变类型:不可变类型一旦创建无法更改;可变类型可以更改且会影响所有引用。
  • 浅拷贝与深拷贝:浅拷贝共享嵌套对象引用,深拷贝完全独立,适用于复杂嵌套结构的复制。

Python float类型的比较

在 Python 中比较浮点数时,由于浮点数的精度限制,直接使用 == 来判断两个浮点数是否相等通常是不可靠的。可以通过设置比较精度(容许误差)来判断两个浮点数是否在特定范围内相等。常用的方法如下:

1. 使用内置的 math.isclose() 函数

Python 3.5 引入了 math.isclose() 函数,用于比较两个浮点数是否接近相等。此函数允许设置相对误差和绝对误差,以控制比较精度。

import math

a = 0.1 + 0.2
b = 0.3

# 使用默认精度(相对误差 1e-09)
print(math.isclose(a, b))  # 输出: True

# 设置更高的精度
print(math.isclose(a, b, rel_tol=1e-10, abs_tol=1e-10))
  • rel_tol:相对误差容忍度,默认为 1e-09
  • abs_tol:绝对误差容忍度,默认值为 0.0。适合比较非常小的数时使用。

2. 使用自定义误差范围

如果需要手动设置精度,也可以通过自定义误差范围进行比较。

def is_close(a, b, tol=1e-9):
return abs(a - b) < tol

a = 0.1 + 0.2
b = 0.3
print(is_close(a, b)) # 输出: True

3. 使用 decimal 模块

对于高精度计算,decimal 模块可以更精确地控制小数位数。将浮点数转换为 Decimal 对象后,可以设定精度进行比较。

from decimal import Decimal, getcontext

# 设置精度
getcontext().prec = 10

a = Decimal('0.1') + Decimal('0.2')
b = Decimal('0.3')
print(a == b) # 输出: True

4. 使用 numpy.isclose()(适合科学计算)

numpy.isclose() 是 NumPy 提供的类似 math.isclose() 的函数,适用于比较数组中的浮点数。

import numpy as np

a = 0.1 + 0.2
b = 0.3
print(np.isclose(a, b)) # 输出: True

STM32 HAL库进行IIC通信时设置的地址与设备七位地址不同,为何能正常通信?

调试AHT20,STM32 HAL库进行IIC通信时设置的地址是0x70,而外设数据手册中的地址是0x38,逻辑分析仪捕获到的地址也是0x38

原来0x38是设备的真实地址(7位),HAL库函数要求传入的是左移一位后的地址(8位),0x38左移一位后变成0x70

Keil程序无法下载到国产盗版STM32:Connection refused due to device mismatch!

原因:国产/盗版芯片id不同,新版keil拒绝下载

解决办法:

Settings

取消勾选Enable

成功下载!

四川移动-内网网络打印机无法使用

省流:DNS问题,换用阿里dns解决

排查,直接访问打印机ip地址正常,但驱动通过主机名访问打印机

四川移动运营商dns为何返回127.0.0.2?

换用阿里,解析正常,访问正常,打印恢复

有没有大佬科普一下为啥QwQ,主机名解析的流程?是移动DNS的问题吗?

双网口机器固定ip失效

注意网口是否插错?不同口mac不同

喜马拉雅音频爬取

以前写的版本不能用了?

原接口不返回数据了…

前后端通讯加密

1 hours later

gpt改写,再改改,解密终版如下

DD1 = [183, 174, 108, 16, 131, 159, 250, 5, 239, 110, 193, 202, 153, 137, 251, 176, 119, 150, 47, 204, 97, 237, 1, 71, 177, 42, 88, 218, 166, 82, 87, 94, 14, 195, 69, 127, 215, 240, 225, 197, 238, 142, 123, 44, 219, 50, 190, 29, 181, 186, 169, 98, 139, 185, 152, 13, 141, 76, 6, 157, 200, 132, 182, 49, 20, 116, 136, 43, 155, 194, 101, 231, 162, 242, 151, 213, 53, 60, 26, 134, 211, 56, 28, 223, 107, 161, 199, 15, 229, 61, 96, 41, 66, 158, 254, 21, 165, 253, 103, 89, 3, 168, 40, 246, 81, 95, 58, 31, 172, 78, 99, 45, 148, 187, 222, 124, 55, 203, 235, 64, 68, 149, 180, 35, 113, 207, 118, 111, 91, 38, 247, 214, 7, 212, 209, 189, 241, 18, 115, 173, 25, 236, 121, 249, 75, 57, 216, 10, 175, 112, 234, 164, 70, 206, 198, 255, 140, 230, 12, 32, 83, 46, 245, 0, 62, 227, 72, 191, 156, 138, 248, 114, 220, 90, 84, 170, 128, 19, 24, 122, 146, 80, 39, 37, 8, 34, 22, 11, 93, 130, 63, 154, 244, 160, 144, 79, 23, 133, 92, 54, 102, 210, 65, 67, 27, 196, 201, 106, 143, 52, 74, 100, 217, 179, 48, 233, 126, 117, 184, 226, 85, 171, 167, 86, 2, 147, 17, 135, 228, 252, 105, 30, 192, 129, 178, 120, 36, 145, 51, 163, 77, 205, 73, 4, 188, 125, 232, 33, 243, 109, 224, 104, 208, 221, 59, 9]
FF1 = [204, 53, 135, 197, 39, 73, 58, 160, 79, 24, 12, 83, 180, 250, 101, 60, 206, 30, 10, 227, 36, 95, 161, 16, 135, 150, 235, 116, 242, 116, 165, 171]
# 两个秘钥
# 定义 a 函数
def a(e, t, r):
    n = min(len(e) - t, len(r))
    for o in range(n):
        e[o + t] = e[o + t] ^ r[o]
    return e

# 定义 b 函数
def decrypt(e):
    print(e.replace("_", "/").replace("-", "+"))
    t = base64.b64decode(e.replace("_", "/").replace("-", "+"))
    if len(t) < 16:
        return e
    r = array.array('B', t[:-16])  # 创建新的字节数组,只包含除最后16个字节之外的部分
    u = array.array('B', t[-16:])  # 创建新的字节数组,只包含最后16个字节
    for s in range(len(r)):
        r[s] = DD1[r[s]]  # DD1需要预先定义为一个对应的值映射
    for l in range(0, len(r), 16):
        r = a(r, l, u)  # 对字节数组进行异或操作
    for f in range(0, len(r), 32):
        r = a(r, f, FF1)  # FF1也需要预先定义为一个对应的值映射
    return r.tobytes().decode()  # 将结果转回字符串

原来这叫urlsafe encode

完整代码

import requests,json,os,time,base64,array,time
"""
23.9.24 下载策略更新&跳过策略&新建文件夹
24.1.23 专辑数据保存,文件名称修复,链接居然加密整死人了,qtmd
"""
TRACK_LIST_URL = 'https://www.ximalaya.com/revision/album/v1/getTracksList'
AUDIO_URL = 'https://www.ximalaya.com/revision/play/v1/audio'
AUDIO_URL_V2 = 'https://www.ximalaya.com/mobile-playpage/track/v3/baseInfo/'
COOKIE = r''
DD1 = [183, 174, 108, 16, 131, 159, 250, 5, 239, 110, 193, 202, 153, 137, 251, 176, 119, 150, 47, 204, 97, 237, 1, 71, 177, 42, 88, 218, 166, 82, 87, 94, 14, 195, 69, 127, 215, 240, 225, 197, 238, 142, 123, 44, 219, 50, 190, 29, 181, 186, 169, 98, 139, 185, 152, 13, 141, 76, 6, 157, 200, 132, 182, 49, 20, 116, 136, 43, 155, 194, 101, 231, 162, 242, 151, 213, 53, 60, 26, 134, 211, 56, 28, 223, 107, 161, 199, 15, 229, 61, 96, 41, 66, 158, 254, 21, 165, 253, 103, 89, 3, 168, 40, 246, 81, 95, 58, 31, 172, 78, 99, 45, 148, 187, 222, 124, 55, 203, 235, 64, 68, 149, 180, 35, 113, 207, 118, 111, 91, 38, 247, 214, 7, 212, 209, 189, 241, 18, 115, 173, 25, 236, 121, 249, 75, 57, 216, 10, 175, 112, 234, 164, 70, 206, 198, 255, 140, 230, 12, 32, 83, 46, 245, 0, 62, 227, 72, 191, 156, 138, 248, 114, 220, 90, 84, 170, 128, 19, 24, 122, 146, 80, 39, 37, 8, 34, 22, 11, 93, 130, 63, 154, 244, 160, 144, 79, 23, 133, 92, 54, 102, 210, 65, 67, 27, 196, 201, 106, 143, 52, 74, 100, 217, 179, 48, 233, 126, 117, 184, 226, 85, 171, 167, 86, 2, 147, 17, 135, 228, 252, 105, 30, 192, 129, 178, 120, 36, 145, 51, 163, 77, 205, 73, 4, 188, 125, 232, 33, 243, 109, 224, 104, 208, 221, 59, 9]
FF1 = [204, 53, 135, 197, 39, 73, 58, 160, 79, 24, 12, 83, 180, 250, 101, 60, 206, 30, 10, 227, 36, 95, 161, 16, 135, 150, 235, 116, 242, 116, 165, 171]
# 两个秘钥
# 定义 a 函数
def a(e, t, r):
    n = min(len(e) - t, len(r))
    for o in range(n):
        e[o + t] = e[o + t] ^ r[o]
    return e

# 定义 b 函数
def decrypt(e):
    #print(e.replace("_", "/").replace("-", "+"))
    missing_padding = 4 - len(e) % 4
    if missing_padding:
        e += '='* missing_padding
    t = base64.urlsafe_b64decode(e)
    if len(t) < 16:
        return e
    r = array.array('B', t[:-16])  # 创建新的字节数组,只包含除最后16个字节之外的部分
    u = array.array('B', t[-16:])  # 创建新的字节数组,只包含最后16个字节
    for s in range(len(r)):
        r[s] = DD1[r[s]]  # DD1需要预先定义为一个对应的值映射
    for l in range(0, len(r), 16):
        r = a(r, l, u)  # 对字节数组进行异或操作
    for f in range(0, len(r), 32):
        r = a(r, f, FF1)  # FF1也需要预先定义为一个对应的值映射
    return r.tobytes().decode()  # 将结果转回字符串

def download(URL,NAME):
    print(f'开始下载{NAME}...')
    if(os.path.exists(NAME+'.mp3')):
        print(f"{NAME}已下载,跳过...")
        return
    with open(NAME+'.mp3','wb+') as f:
        f.write(requests.get(URL).content)
    print(f'{NAME}下载完成!')
def namerepair(name:str) -> str:    # 文件名规范
    name = name.replace('/',' ')
    name = name.replace('/\/',' ')
    name = name.replace(':',' ')
    name = name.replace('*',' ')
    name = name.replace('?',' ')
    name = name.replace('"',' ')
    name = name.replace('<',' ')
    name = name.replace('>',' ')
    name = name.replace('|',' ')
    return name
class album:
    tracks:list = []
    albumId:str = ''
    name:str = ''
    totalTracks:int = 0
    def saveData(self) -> bool:
        with open(f"{self.albumId}.albumdata",'w+',encoding='utf-8') as f:
            selfData = {
                'name':self.name,
                'tracks':self.tracks,
                'totalTracks':self.totalTracks,
                'albumId':self.albumId
            }
            f.write(json.dumps(selfData))
            f.close()
        return True
    def getTracks(self) -> bool:
        header = {
            'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.69',
            'cookie':COOKIE
        }
        param = {
            'albumId':self.albumId,
            'pageNum':1,
            'pageSize':30,
            'sort':0
        }
        ret = requests.get(TRACK_LIST_URL,params = param,headers=header)
        ret = json.loads(ret.text)
        self.name = ret['data']['tracks'][0]['albumTitle']
        self.totalTracks = ret['data']['trackTotalCount']
        self.tracks:list = ret['data']['tracks']
        rest = self.totalTracks - param['pageSize']
        pageNo = 1
        while(rest >= 0):
            print(f'获取专辑详情,第{pageNo}页')
            time.sleep(1)
            pageNo += 1
            param['pageNum'] = pageNo
            rest -= param['pageSize']
            ret = requests.get(TRACK_LIST_URL,params = param,headers=header)
            ret = json.loads(ret.text)
            self.tracks.extend(ret['data']['tracks'])
        self.saveData()
        return True
    def downloadAll(self) -> None:
        #pool = ThreadPoolExecutor(max_workers=4)
        dir = namerepair(self.name)
        if(not os.path.exists(dir)):
            os.mkdir(dir)
        for j in range(len(self.tracks)):
            i = self.tracks[j]
            tt = namerepair(i['title'])
            if(os.path.exists(f'{dir}\\{tt}'+'.mp3')):
                print(f'{dir}\\{tt}已下载,跳过...')
                continue
            header = {
                'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.69',
                'Cookie':COOKIE,
                'Host': 'www.ximalaya.com'
            }
            param = {
                'trackId':i['trackId'],
                'device':'www2',
                'trackQualityLevel':1,

            }
            #print(i['trackId'])
            timeUrl = f'{AUDIO_URL_V2}{int(round(time.time() * 1000))}'
            ret = requests.get(timeUrl,params = param,headers=header)
            #ret = requests.get('https://www.ximalaya.com/mobile-playpage/track/v3/baseInfo/1706016965133?device=www2&trackId=491707341&trackQualityLevel=1',headers=header)
            time.sleep(0.5)
            au = json.loads(ret.text)
            au = au['trackInfo']['playUrlList'][1]['url']
            au = decrypt(au)
            while 1:
                try:
                    download(au,f'{dir}\\{tt}')
                except:
                    print('下载出错,1s重试')
                    time.sleep(1)
                    continue
                break
    def __init__(self,albumId:str,refresh:bool = False):
        self.albumId = albumId
        if(os.path.exists(f"{self.albumId}.albumdata") and refresh == False):
            with open(f"{self.albumId}.albumdata",encoding='utf-8') as f:
                data = f.read()
                data = json.loads(data)
                self.name = data['name']
                self.tracks = data['tracks']
                self.totalTracks = data['totalTracks']
                self.albumId = data['albumId']
        else:
            self.getTracks()
        print(self.name)
v = album('56206086')
v.downloadAll()

侵删 ch939367561#hotmail.com(#->@)

Ubuntu 根目录扩容

ubuntu扩容根目录_Fzuim的博客-CSDN博客

四川移动 openwrt 双路由器 iptv 单线复用以及ipv6

主路由 mi4A 千兆版刷openwrt,另一个H3C nx30pro(问就是H3C放外面信号更好)

H3C中继模式WAN接Mi4A LAN2,Mi4A WAN接光猫LAN1

配置部分

光猫

四川移动光猫密码超级随机,向安装师傅电话查询。

网络->绑定设置

wan 3为iptv,2为网络,宽带设置取消所有LAN口绑定。

Mi4A

接口->设备->添加新网桥

接口->wan

ipv6下游地址分配配置:

ra标记添加受管配置下游设备可获取一个较为规整的地址,但不启用SLAAC下游电脑正常手机无法获取ipv6地址

H3C

光猫已设桥接,路由拨号上网正常,盒子连 H3C LAN2 大功告成~

Homeassistant edge_tts+browser_mod TTS播放踩坑合集

原参考链接:音乐播放器接入homeassistant | 智能家居 | 全屋智能音响 | nodered_哔哩哔哩_bilibili

不行,报no tts from edge_tts for …… 且browser_mod 中间差了一步添加集成。

去全球最大同性交友社区看看……

提示no tts from edge_tts for …… · Issue #8 · hasscc/hass-edge-tts · GitHub

但是——其实解决的时候并没翻到这个issue,所以把browser_mod,edge_tts,hass都升级到了最新版本(?)

报错:Unable to set up dependencies of esphome. Setup failed for dependencies: assist_pipeline

百度啥也没有,Google一下

解决~然后是tts: Unknown Error

查日志:Volume must be str

四处排查原因,结果是原链接给的配置文件中 volumn 是个100.00 ……可能新版本有变化 直接删掉

tts:
  - platform: edge_tts
    service_name: xiaomo_say
    language: zh-CN-XiaomoNeural

总结:能用就别升级~有问题找官方文档~

Page 1 of 2

Powered by WordPress & Theme by Anders Norén