class Bit():
def __init__(self,word:int):
'''
:param word: 0-65535
'''
self.word = word
def get(self,postion:int)->bool:
w = self.word & 1 << postion
return bool(w)
def write(self,postion:int,value:bool)->None:
'''
:param postion: 位索引 范围0-15
:param value: True or False
:return: None
'''
if value:
self.word = self.word | 1 << postion
else:
self.word = self.word & ~1 << postion
def __str__(self):
return f'十进制:{self.word}, 二进制:{bin(self.word)[2:].zfill(16)}'
在上位机开发中,经常要进行位运算。一般通过通讯协议从下位机(plc ,仪器,仪表,传感器等)接受数据,数据一般都是整形数据,范围为(0-65535)。这时在上位机就要对这些数据进行解析到某个位,然后就可以对这个位进行读写操作。这里给出对一个16位的数据进行了封装,代码虽然冗余,但容易理解。后期在对代码进行优化,加入装饰器及魔法方法,那样代码就简洁了。
class IntToBit(object):
#获取或设置一个字(16位整数)的位状态
def __init__(self,world:int):
if not isinstance(world,int):
raise StopIteration('数据类型错误')
if world<0 or world>65535:
raise StopIteration('数据小于0或大于65535')
self.world=world
def __str__(self):print(bin(self.world))
def _get_0(self):return bin(self.world & 0x0001)
def _get_1(self):return bin(self.world & 0x0002)
def _get_2(self):return bin(self.world & 0x0004)
def _get_3(self):return bin(self.world & 0x0008)
def _get_4(self):return bin(self.world & 0x0010)
def _get_5(self):return bin(self.world & 0x0020)
def _get_6(self):return bin(self.world & 0x0040)
def _get_7(self):return bin(self.world & 0x0080)
def _get_8(self):return bin(self.world & 0x0100)
def _get_9(self):return bin(self.world & 0x0200)
def _get_10(self):return bin(self.world & 0x0400)
def _get_11(self):return bin(self.world & 0x0800)
def _get_12(self):return bin(self.world & 0x1000)
def _get_13(self):return bin(self.world & 0x2000)
def _get_14(self):return bin(self.world & 0x4000)
def _get_15(self):return bin(self.world & 0x8000)
def _set_0(self,num:bool):
if not isinstance(num,bool):
raise StopIteration('数据类型不是布尔')
if num:
self.world = self.world | 0x0001
else:
self.world = self.world & 0xfffe
def _set_1(self, num: bool):
if not isinstance(num, bool):
raise StopIteration('数据类型不是布尔')
if num:
self.world = self.world | 0x0002
else:
self.world = self.world & 0xfffd
def _set_2(self, num: bool):
if not isinstance(num, bool):
raise StopIteration('数据类型不是布尔')
if num:
self.world = self.world | 0x0004
else:
self.world = self.world & 0xfffb
def _set_3(self, num: bool):
if not isinstance(num, bool):
raise StopIteration('数据类型不是布尔')
if num:
self.world = self.world | 0x0008
else:
self.world = self.world & 0xfff7
def _set_4(self, num: bool):
if not isinstance(num, bool):
raise StopIteration('数据类型不是布尔')
if num:
self.world = self.world | 0x0010
else:
self.world = self.world & 0xffef
def _set_5(self, num: bool):
if not isinstance(num, bool):
raise StopIteration('数据类型不是布尔')
if num:
self.world = self.world | 0x0020
else:
self.world = self.world & 0xffdf
def _set_6(self, num: bool):
if not isinstance(num, bool):
raise StopIteration('数据类型不是布尔')
if num:
self.world = self.world | 0x0040
else:
self.world = self.world & 0xffbf
def _set_7(self, num: bool):
if not isinstance(num, bool):
raise StopIteration('数据类型不是布尔')
if num:
self.world = self.world | 0x0080
else:
self.world = self.world & 0xff7f
def _set_8(self, num: bool):
if not isinstance(num, bool):
raise StopIteration('数据类型不是布尔')
if num:
self.world = self.world | 0x0100
else:
self.world = self.world & 0xfeff
def _set_9(self, num: bool):
if not isinstance(num, bool):
raise StopIteration('数据类型不是布尔')
if num:
self.world = self.world | 0x0200
else:
self.world = self.world & 0xfdff
def _set_10(self, num: bool):
if not isinstance(num, bool):
raise StopIteration('数据类型不是布尔')
if num:
self.world = self.world | 0x0400
else:
self.world = self.world & 0xfbff
def _set_11(self, num: bool):
if not isinstance(num, bool):
raise StopIteration('数据类型不是布尔')
if num:
self.world = self.world | 0x0800
else:
self.world = self.world & 0xf7ff
def _set_12(self, num: bool):
if not isinstance(num, bool):
raise StopIteration('数据类型不是布尔')
if num:
self.world = self.world | 0x1000
else:
self.world = self.world & 0xefff
def _set_13(self, num: bool):
if not isinstance(num, bool):
raise StopIteration('数据类型不是布尔')
if num:
self.world = self.world | 0x2000
else:
self.world = self.world & 0xdfff
def _set_14(self, num: bool):
if not isinstance(num, bool):
raise StopIteration('数据类型不是布尔')
if num:
self.world = self.world | 0x4000
else:
self.world = self.world & 0xdfff
def _set_15(self, num: bool):
if not isinstance(num, bool):
raise StopIteration('数据类型不是布尔')
if num:
self.world = self.world | 0x8000
else:
self.world = self.world & 0x7fff
_0=property(_get_0,_set_0)
_1=property(_get_1,_set_1)
_2=property(_get_2,_set_2)
_3=property(_get_3,_set_3)
_4=property(_get_4,_set_4)
_5=property(_get_5,_set_5)
_6=property(_get_6,_set_6)
_7=property(_get_7,_set_7)
_8=property(_get_8,_set_8)
_9=property(_get_9,_set_9)
_10=property(_get_10,_set_10)
_11=property(_get_11,_set_11)
_12=property(_get_12,_set_12)
_13=property(_get_13,_set_13)
_14=property(_get_14,_set_14)
_15=property(_get_15,_set_15)
if __name__=='__main__':
#测试代码
# 20=10100=0x14
v=IntToBit(20) #创建以个对象,这里传入的数据为20
#显示数据当前状态
print(v)
# 0b10100
#查询第1位的状态
print(v._0)
#0b0
#将第一位状态设置为True
v._0=True
print(v._0)
#0b1
#查看当前字状态
print(v)
#0b10101
#将第16位设位True
v._15=True
print(v._15)
#0b1000000000000000
print(v)
#0b1000000000010101
网上对位运算的案例比较少,理解起来一般比较肤浅。经过一位高才生的修改,上面代码瞬间优化了很多。对位的处理也有了深刻理解。位运算中左移和右移比较有意思,先解释下概念,N< 上面的代码有个错误,proprety属性时,不能对fget()方法传参数只好去调用 类方法。不过可以用魔法方法实现这个功能。 把上面代码再一次优化,加入装饰器和断言 对上面代码再次处理,如何生成不同的装饰器在去装饰不同的函数,本例中加入要对函数里的参数类型,数据范围进行限制,比如f1(x,y,z)要求x 为int,y=0,z=100, f2(x,y,z)要求x为str,y=10,z=20等等,那怎么办呢?要么对没一个函数分别写一个装饰器,还有一个方法就是在创建一个函数,这个函数的功能就是生成不同的装饰器,然后再用该装饰器去装饰不同的函数。这里面确实很绕,也是装饰器最难以理解的地方。我也是想了好久,才明白。其实这样写代码比较晦涩,实际很少这样用吧 优化数字数字显示, modbus通讯,数据类型转换
class IntToBit(object):
# 获取或设置一个字(16位整数)的位状态
def __init__(self, world: int):
if not isinstance(world, int):
raise StopIteration('数据类型错误')
if world < 0 or world > 65535:
raise StopIteration('数据小于0或大于65535')
self.world = world
def __str__(self): return (str(bin(self.world)))
def get(self, flag: int):
return bin(self.world & (1 << flag))
def set(self, flag: int, num: bool):
if not isinstance(num, bool):
raise StopIteration('数据类型不是布尔')
if num:
self.world = self.world | (1 << flag)
else:
self.world = self.world & (65535 - (1 << flag))
# def _get_0(self): return bin(self.world & 0x0001)
# def _get_1(self): return bin(self.world & 0x0002)
# def _get_2(self): return bin(self.world & 0x0004)
# def _get_3(self): return bin(self.world & 0x0008)
# def _get_4(self): return bin(self.world & 0x0010)
# def _get_5(self): return bin(self.world & 0x0020)
# def _get_6(self): return bin(self.world & 0x0040)
# def _get_7(self): return bin(self.world & 0x0080)
# def _get_8(self): return bin(self.world & 0x0100)
# def _get_9(self): return bin(self.world & 0x0200)
# def _get_10(self): return bin(self.world & 0x0400)
# def _get_11(self): return bin(self.world & 0x0800)
# def _get_12(self): return bin(self.world & 0x1000)
# def _get_13(self): return bin(self.world & 0x2000)
# def _get_14(self): return bin(self.world & 0x4000)
# def _get_15(self): return bin(self.world & 0x8000)
# def _set_0(self, num: bool):
# if not isinstance(num, bool):
# raise StopIteration('数据类型不是布尔')
# if num:
# self.world = self.world | 0x0001
# else:
# self.world = self.world & 0xfffe
# def _set_1(self, num: bool):
# if not isinstance(num, bool):
# raise StopIteration('数据类型不是布尔')
# if num:
# self.world = self.world | 0x0002
# else:
# self.world = self.world & 0xfffd
# def _set_2(self, num: bool):
# if not isinstance(num, bool):
# raise StopIteration('数据类型不是布尔')
# if num:
# self.world = self.world | 0x0004
# else:
# self.world = self.world & 0xfffb
# def _set_3(self, num: bool):
# if not isinstance(num, bool):
# raise StopIteration('数据类型不是布尔')
# if num:
# self.world = self.world | 0x0008
# else:
# self.world = self.world & 0xfff7
# def _set_4(self, num: bool):
# if not isinstance(num, bool):
# raise StopIteration('数据类型不是布尔')
# if num:
# self.world = self.world | 0x0010
# else:
# self.world = self.world & 0xffef
# def _set_5(self, num: bool):
# if not isinstance(num, bool):
# raise StopIteration('数据类型不是布尔')
# if num:
# self.world = self.world | 0x0020
# else:
# self.world = self.world & 0xffdf
# def _set_6(self, num: bool):
# if not isinstance(num, bool):
# raise StopIteration('数据类型不是布尔')
# if num:
# self.world = self.world | 0x0040
# else:
# self.world = self.world & 0xffbf
# def _set_7(self, num: bool):
# if not isinstance(num, bool):
# raise StopIteration('数据类型不是布尔')
# if num:
# self.world = self.world | 0x0080
# else:
# self.world = self.world & 0xff7f
# def _set_8(self, num: bool):
# if not isinstance(num, bool):
# raise StopIteration('数据类型不是布尔')
# if num:
# self.world = self.world | 0x0100
# else:
# self.world = self.world & 0xfeff
# def _set_9(self, num: bool):
# if not isinstance(num, bool):
# raise StopIteration('数据类型不是布尔')
# if num:
# self.world = self.world | 0x0200
# else:
# self.world = self.world & 0xfdff
# def _set_10(self, num: bool):
# if not isinstance(num, bool):
# raise StopIteration('数据类型不是布尔')
# if num:
# self.world = self.world | 0x0400
# else:
# self.world = self.world & 0xfbff
# def _set_11(self, num: bool):
# if not isinstance(num, bool):
# raise StopIteration('数据类型不是布尔')
# if num:
# self.world = self.world | 0x0800
# else:
# self.world = self.world & 0xf7ff
# def _set_12(self, num: bool):
# if not isinstance(num, bool):
# raise StopIteration('数据类型不是布尔')
# if num:
# self.world = self.world | 0x1000
# else:
# self.world = self.world & 0xefff
# def _set_13(self, num: bool):
# if not isinstance(num, bool):
# raise StopIteration('数据类型不是布尔')
# if num:
# self.world = self.world | 0x2000
# else:
# self.world = self.world & 0xdfff
# def _set_14(self, num: bool):
# if not isinstance(num, bool):
# raise StopIteration('数据类型不是布尔')
# if num:
# self.world = self.world | 0x4000
# else:
# self.world = self.world & 0xdfff
# def _set_15(self, num: bool):
# if not isinstance(num, bool):
# raise StopIteration('数据类型不是布尔')
# if num:
# self.world = self.world | 0x8000
# else:
# self.world = self.world & 0x7fff
#_value = property(_get, _set)
# _0 = property(_get_0, _set_0)
# _1 = property(_get_1, _set_1)
# _2 = property(_get_2, _set_2)
# _3 = property(_get_3, _set_3)
# _4 = property(_get_4, _set_4)
# _5 = property(_get_5, _set_5)
# _6 = property(_get_6, _set_6)
# _7 = property(_get_7, _set_7)
# _8 = property(_get_8, _set_8)
# _9 = property(_get_9, _set_9)
# _10 = property(_get_10, _set_10)
# _11 = property(_get_11, _set_11)
# _12 = property(_get_12, _set_12)
# _13 = property(_get_13, _set_13)
# _14 = property(_get_14, _set_14)
# _15 = property(_get_15, _set_15)
class IntToBit(object):
def __init__(self,word:int):
if not isinstance(word,int):
raise StopIteration('数据类型不对')
if word<0 or word>65535:
raise StopIteration("数字不在范围")
self.word=word
def __getitem__(self, key):
if not isinstance(key, int):
raise StopIteration('数据类型错误')
if (key<0) or (key > 16):
raise StopIteration("数字不在范围")
return bin(self.word & (1<
class IntToBit:
def __check_init(func):
def inner(self,value):
if not isinstance(value,int):
raise StopIteration("数据类型不匹配")
return func(self,value)
return inner
@__check_init
def __init__(self,v:int):
assert 0<=v<=65535,"超出范围"
self.v = v
def __str__(self):
return "{} 的二进制数为0b: {}".format(self.v,bin(self.v))
__repr__=__str__
@__check_init
def __getitem__(self, index):
assert 0<=index<=15,"超出范围,应为0-15之间"
return bin(self.v & (1<
class IntToBit:
def __getzsq(type,min,max):
'''
生成不同装饰器
:param type: 数据类型
:param min: 数据最小值
:param max: 数据最大值
:return: 返回装饰器
'''
def check_init(func):
def inner(self, value):
if not isinstance(value, type):
raise StopIteration("数据类型不匹配")
if value
class IntToBit:
def __getzsq(type,min,max):
'''
生成不同装饰器
:param type: 数据类型
:param min: 数据最小值
:param max: 数据最大值
:return: 返回装饰器
'''
def check_init(func):
def inner(self, value):
if not isinstance(value, type):
raise StopIteration("数据类型不匹配")
if value
word = 0b1111_1001
def f(n):
global word
w= word & 1<
import struct
def ReadFloat(*args,reverse=False):
for n,m in args:
n,m = '%04x'%n,'%04x'%m
if reverse:
v = n + m
else:
v = m + n
y_bytes = bytes.fromhex(v)
y = struct.unpack('!f',y_bytes)[0]
y = round(y,6)
return y
def WriteFloat(value,reverse=False):
y_bytes = struct.pack('!f',value)
# y_hex = bytes.hex(y_bytes)
y_hex = ''.join(['%02x' % i for i in y_bytes])
n,m = y_hex[:-4],y_hex[-4:]
n,m = int(n,16),int(m,16)
if reverse:
v = [n,m]
else:
v = [m,n]
return v
def ReadDint(*args,reverse=False):
for n,m in args:
n,m = '%04x'%n,'%04x'%m
if reverse:
v = n + m
else:
v = m + n
y_bytes = bytes.fromhex(v)
y = struct.unpack('!i',y_bytes)[0]
return y
def WriteDint(value,reverse=False):
y_bytes = struct.pack('!i',value)
# y_hex = bytes.hex(y_bytes)
y_hex = ''.join(['%02x' % i for i in y_bytes])
n,m = y_hex[:-4],y_hex[-4:]
n,m = int(n,16),int(m,16)
if reverse:
v = [n,m]
else:
v = [m,n]
return v
if __name__ == "__main__":
# print(ReadFloat((62915,16456 )))
# print(WriteFloat(3.16))
print(ReadDint((94,14)))
# print(WriteDint(456787654))