我编写了两个Python函数,用于使用两种不同的方法将表示元组的图像的RGB颜色转换为单个整数值。
为了测试两种方法是否提供相同的结果,有必要经常在两个代码段之间切换,选择应该运行哪一个。
最后我决定只使用其中一种方法,但决定将另一种方法保留在脚本代码中,因为它可以更好地演示代码的功能。
为了"关闭"一个代码块并"打开"另一个代码块,我使用了两种不同的方法:if
代码块(参见下面代码中的函数之一)和一个三重引号字符串。
第一种方法(使用if
)需要在代码中引入额外的缩进,另一种方法需要使用中间的三引号将带有三引号的行从底部移动到代码块的顶部。两种方法都可以,但是…
是否有更好更简单的方法来进行这种切换?如果它只需要按键盘上的一个键一次,以便在两个代码块之间切换?
下面是我的代码:
# ======================================================================
''' Conversion functions for single RGB-color values '''
def rgb2int(rgb_tuple):
if 1: # <<< change to 0 to switch to the else: part of code
from sys import byteorder as endian
# endianiness = sys.byteorder # 'little'
int_rgb = int.from_bytes(bytearray(rgb_tuple), endian) # ,signed=False)
else:
if len(rgb_tuple) == 4: # RGBA tuple
R,G,B,A = rgb_tuple
else:
R,G,B = rgb_tuple
A = None
if A is not None:
int_rgb =( 0 ) + A
else:
int_rgb = 0
int_rgb = (int_rgb<<8) + B
int_rgb = (int_rgb<<8) + G # ! int_rgb<<8 + G == int_rgb<<(8+G) !
int_rgb = (int_rgb<<8) + R
return int_rgb
def int2rgb(int_rgb, alpha=False):
from sys import byteorder as endian
tplsize = 4 if alpha else 3
rgb_tuple = tuple(int_rgb.to_bytes(tplsize, endian)) # ,signed=False))
"""
if not alpha:
rgb_tuple = (
int_rgb & 0xff,
( int_rgb >> 8 ) & 0xff,
( int_rgb >> 16 ) & 0xff )
else: # with alpha channel:
rgb_tuple = (
int_rgb & 0xff,
( int_rgb >> 8 ) & 0xff,
( int_rgb >> 16 ) & 0xff,
( int_rgb >> 24 ) & 0xff )
""" # <<< move to top to switch to the code block above
return rgb_tuple
rgb = (32,253,200,100)
int_rgb = rgb2int(rgb)
rgb_ = int2rgb(int_rgb, alpha=True)
print(rgb, int_rgb, rgb_, sep='n')
assert rgb == rgb_
rgb = (32,253,200)
int_rgb = rgb2int(rgb)
rgb_ = int2rgb(int_rgb)
assert rgb == rgb_
# ---
if __name__ == "__main__":
print(' --- ')
print(rgb)
print(int_rgb)
print(rgb_)
#This gives:
[32, 253, 200]
13172000
[32, 253, 200]
UPDATE because of response:
回应一个注释,解释为什么我没有选择使用两个不同的函数来分隔代码片段:
两个单独的函数会将属于一个函数的代码部分分开,并且有必要在代码中解释这两个函数尽管有不同的名称,但它们的功能完全相同。
用例是测试代码的两个部分在编辑它们的代码后是否实际上完全相同,以便决定以后使用哪个版本。在这个例子中,第二个代码块可以用来解释另一个代码块的作用,所以把它保留在函数中是有意义的,尽管它不会被使用。
不要写一个函数做两件不同的事情。写两个函数,每个函数只做一件事:
def rgb2int_v1(rgb_tuple):
from sys import byteorder as endian
# endianiness = sys.byteorder # 'little'
int_rgb = int.from_bytes(bytearray(rgb_tuple), endian) # ,signed=False)
return int_rgb
def rgb2int_v2(rgb_tuple):
if len(rgb_tuple) == 4: # RGBA tuple
R,G,B,A = rgb_tuple
else:
R,G,B = rgb_tuple
A = None
if A is not None:
int_rgb =( 0 ) + A
else:
int_rgb = 0
int_rgb = (int_rgb<<8) + B
int_rgb = (int_rgb<<8) + G # ! int_rgb<<8 + G == int_rgb<<(8+G) !
int_rgb = (int_rgb<<8) + R
return int_rgb
然后在脚本开头选择要使用的版本:
rgb2int = rgb2int_v1 if use_v1 else rgb2int_v2
其中use_v1
是一个变量,您可以通过编辑脚本设置,或者最好通过解析命令行选项,以便您可以在每次运行之间切换而无需编辑脚本。
使用行注释'#'
字符和三引号"""
的智能组合,可以在Python中在两个代码块之间切换,就像在键盘上按下[Del]
或[#]
一样。
查看下面的代码是如何完成的,并享受"魔法"。
# ======================================================================
''' Conversion functions for single RGB-color values '''
def rgb2int(rgb_tuple):
#""" <<< remove or add '#' to 'switch' between the two code blocks
from sys import byteorder as endian
# endianiness = sys.byteorder # 'little'
int_rgb = int.from_bytes(bytearray(rgb_tuple), endian) # ,signed=False)
"""
if len(rgb_tuple) == 4: # RGBA tuple
R,G,B,A = rgb_tuple
else:
R,G,B = rgb_tuple
A = None
if A is not None:
int_rgb =( 0 ) + A
else:
int_rgb = 0
int_rgb = (int_rgb<<8) + B
int_rgb = (int_rgb<<8) + G # ! int_rgb<<8 + G == int_rgb<<(8+G) !
int_rgb = (int_rgb<<8) + R
# """ # the TRICK is to use a line comment before triple quotes
return int_rgb
def int2rgb(int_rgb, alpha=False):
#""" <<< remove or add '#' to 'switch' between the two code blocks
from sys import byteorder as endian
tplsize = 4 if alpha else 3
rgb_tuple = tuple(int_rgb.to_bytes(tplsize, endian)) # ,signed=False))
"""
if not alpha:
rgb_tuple = (
int_rgb & 0xff,
( int_rgb >> 8 ) & 0xff,
( int_rgb >> 16 ) & 0xff )
else: # with alpha channel:
rgb_tuple = (
int_rgb & 0xff,
( int_rgb >> 8 ) & 0xff,
( int_rgb >> 16 ) & 0xff,
( int_rgb >> 24 ) & 0xff )
# """ # the TRICK is to use a line comment before triple quotes
return rgb_tuple
rgb = (32,253,200,100)
int_rgb = rgb2int(rgb)
rgb_ = int2rgb(int_rgb, alpha=True)
print(rgb, int_rgb, rgb_, sep='n')
assert rgb == rgb_
rgb = (32,253,200)
int_rgb = rgb2int(rgb)
rgb_ = int2rgb(int_rgb)
assert rgb == rgb_
# ---
if __name__ == "__main__":
print(' --- ')
print(rgb)
print(int_rgb)
print(rgb_)
#This gives:
[32, 253, 200]
13172000
[32, 253, 200]
Bye the way:你最终应该避免在你的编码中使用它,除了测试目的.
Python中的三重引号是为了使多行字符串和文档字符串成为可能,使用它们作为一种预处理开关不是'Pythonic'。