python - Python 速记值太多,无法解包错误
问题描述
我收到错误消息too many values to unpack (expected 3)
。当我添加[]
以防它本身是一个元组时,我收到错误not enough values to unpack (expected 3, got 1)
错误在第 50 行上升,r, g, b = hex2rgb(newpix)
我将分享整个代码,因为我不确定这是否是我得到的唯一错误。
我的目标是将字符串插入 .png 文件。大约 10 年前我曾经使用过 python,我是 C# 用户,所以如果这个问题太笨了,请原谅
谢谢 PS我不太擅长表达自己,请随意编辑帖子
from PIL import Image
import binascii
import optparse
def rgb2hex(r, g, b):
return '#{:02x}{:02x}{:02x}'.format(r, g, b)
def hex2rgb(hexcode):
return tuple(map(ord, hexcode[1:]))
def str2bin(message):
binary = bin(int(binascii.hexlify(message.encode()), 16))
return binary[2:]
def bin2str(binary):
message = binascii.unhexlify('%x' % (int('0b' + binary, 2)))
return message
def encode(hexcode, digit):
if hexcode[-1] in ('0', '1', '2', '3', '4', '5'):
hexcode = hexcode[:-1] + digit
return hexcode
else:
return None
def decode(hexcode):
if hexcode[-1] in ('0', '1'):
return hexcode[-1]
else:
return None
def hide(filename, message):
img = Image.open(filename)
binary = str2bin(message) + '1111111111111110'
if img.mode in ('RGBA'):
img = img.convert('RGBA')
datas = img.getdata()
newData = []
digit = 0
temp = ''
for item in datas:
if (digit < len(binary)):
newpix = encode(rgb2hex(item[0], item[1], item[2]), binary[digit])
if newpix == None:
newData.append(item)
else:
r, g, b = [hex2rgb(newpix)]
newData.append((r, g, b, 255))
digit =+ 1
else:
newData.append(item)
img.putdata(newData)
img.save(filename, "PNG")
return "Completed!"
return "Incorrect Image mode, couldn't hide"
def retr(filename):
img = Image.open(filename)
binary = ''
if img.mode in ('RGBA'):
img = img.convert('RGBA')
datas = img.getdata()
for item in datas:
digit = decode(rgb2hex(item[0], item[1], item[2]))
if digit == None:
pass
else:
binary = binary + digit
if (binary[-16:] == '1111111111111110'):
print("Success")
return bin2str(binary[:-16])
return bin2str(binary)
return "Incorrect Image mode, couldn't retrieve"
def Main():
parser = optparse.OptionParser('usage %prog ' + '-e/-d <target file>')
parser.add_option('-e', dest = 'hide', type = 'string', help = 'target picture path to hide text')
parser.add_option('-d', dest = 'retr', type = 'string', help = 'target picture to retrieve text')
(options, args) = parser.parse_args()
if (options.hide != None):
text = input("Enter a message to hide: ")
print(hide(options.hide, text))
elif(options.retr != None):
print(retr(optrions.retr))
else:
print(parser.usage)
exit(0)
if __name__ == '__main__':
Main()
解决方案
>>> hex2rgb('#abcdef')
(97, 98, 99, 100, 101, 102)
在这里,我使用您的hex2rgb()
函数而不将输出分配给任何变量。它返回 6 个值,正如您所期望的,因为您将每个字符从十六进制值(a
例如)解码为对应于十六进制a
:的整数 unicode 代码点97
。(请参见此处的文档或 ord())
>>> r,g,b = hex2rgb('#abcdef')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 3)
尝试将它们解压缩为三个变量时,会引发错误,因为您的函数返回 6 个变量而不是预期的 3 个。
>>> r,g,b = [hex2rgb('#abcdef')]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: not enough values to unpack (expected 3, got 1)
您将 6 个整数包装到列表中的方法将返回值从 6 个变量减少到只有 1 个值(包含 6 个项目的列表),因此这不能解决您的问题。
要解决您的问题,您应该找到一种以 3 个整数而不是 6 个整数结尾的方法。为此,您需要一种不同的方法来解码 HEX 值。
我的示例中的 RGB 对由 Red=AB、Green=CD、Blue=EF 组成。通过使用map()
with ord()
you translateA
并B
单独转换为一个整数,这不是您想要的,因为您最终得到 2 个整数 ( 97
and 98
) 而不是 1 个整数 ( 171
) 对应于该AB
值。
所以你想要的是:
>>> int("0xAB",0)
171
如您所见,AB
一起转换将返回正确的值 (171)。有关如何执行此操作的示例,请参见此答案。修改你的hex2rgb()
来做到这一点。
最后但并非最不重要的一点是,您ord()
将字符解码为整数的方法很有趣,但可能不正确,因为A
它们a
具有不同的 unicode 代码点值 ( A = 65
, a = 97
),因此它们会为您的颜色生成不同的值。在 HEX 颜色代码中,大写或小写字母没有区别。当您使用上述方法时int()
,小写或大写字符的结果将相同,因此更正确。
推荐阅读
- c# - C#+Selenium 网页抓取
- jmeter - How to display the variable value in the summary report
- nginx - 增加 proxy_send_timeout 和 proxy_read_timeout 入口 nginx
- swagger - Add the placeholder required in swagger ui v2.0
- spring - @Value 注释不适用于 STS 3.9.6 上的 Infinitest 5.2.0
- javascript - 单击按钮时从内容脚本打开选项页面?
- html - Webpack 4 不从 HTML 文件加载图像
- java - 禁用所有日期,而不是一个月或一周的第一天
- java - Eclipse 插件:标签中的编码
- javascript - React Native:ScrollView 中的 KeyboardAwareScrollView 不起作用