详情

首页手游攻略 Python位运算符的使用做法和实践场景全解实用指南

Python位运算符的使用做法和实践场景全解实用指南

佚名 2026-11-05 11:00:01

平时做技术实践时,很多问题不是概念不会,而是细节没串起来。拿“Python位运算符的采用做法和实践场景全解”来说,它看着像小点,放到项目里常会牵出环境、配置、兼容性和维护成本。下面按实际采用顺序,把思路、关键写法和容易踩坑的地方讲清楚,便于大家直接对照操作。

一、开篇:为什么要学位运算

很多Python初学者看到&、|、^、<<、>>这些运算符时,第一反应是:“我用Python写业务代码,还需学位运算?”

答案是:需的。虽然位运算不像if-else那样每天都要写,但它在以下场景中无处不在:

  • 权限系统设计(用位表示权限,一个整数代替一堆布尔值)
  • 性能优化(位运算比算术运算快得多)
  • 颜色处理(RGB值的提取与合并)
  • 网络编程(IP地址、子网掩码计算)
  • 数据压缩与加密(底层算法的基础)
  • 状态标记(用一个整数表示多种状态的组合)

更重要的是,理解位运算能让你真正理解计算机是如何看待数据的——毕竟,在底层,一切都是0和1。

落到代码里,今天这篇文章,我们就从二进制基础开始,逐步掌握Python中所有位运算符的采用方法和实战场景。

二、二进制基础速成

2.1 为什么要用二进制

实际处理时,计算机用二进制(而非十进制)存储和处理数据,是因为二进制只需两种状态(开/关、高电压/低电压),这在物理上最容易实现且最可靠。

2.2 二进制与十进制的转换

# Python中表示二进制数:用 0b 或 0B 前缀
a = 0b1010 # 二进制1010 = 十进制10
b = 0b1111 # 二进制1111 = 十进制15

print(a) # 10 —— Python内部以十进制显示
print(b) # 15

# 十进制转二进制字符串
print(bin(10)) # 0b1010
print(bin(255)) # 0b11111111
print(bin(0)) # 0b0

# 格式化为不带前缀的二进制
print(format(10, 'b')) # 1010
print(format(255, '08b')) # 11111111 —— 补齐8位

# 手动转换:十进制 → 二进制(理解原理)
def decimal_to_binary(n):
    """十进制转二进制(正整数)"""
    if n == 0:
        return '0'
    bits = []
    while n > 0:
        bits.append(str(n % 2))
        n //= 2
    return ''.join(reversed(bits))

print(decimal_to_binary(10)) # 1010
print(decimal_to_binary(255)) # 11111111

# 二进制 → 十进制(理解原理)
def binary_to_decimal(binary_str):
    """二进制字符串转十进制"""
    result = 0
    for bit in binary_str:
        result = result * 2 + int(bit)
    return result

print(binary_to_decimal('1010')) # 10
print(binary_to_decimal('11111111')) # 255

2.3 二进制的基本概念

# 比特(bit):二进制的一位,只能是0或1
# 字节(byte):8个比特

# bit 的编号(从右往左,从0开始)
# 二进制:1 0 1 0
# 位号: 3 2 1 0
# 权重: 8 4 2 1

# 每一位的权重是 2 的 n 次方
# 位0: 2^0 = 1
# 位1: 2^1 = 2
# 位2: 2^2 = 4
# 位3: 2^3 = 8
# 1010 = 8 + 0 + 2 + 0 = 10

# 查看一个整数占用的比特数
print((10).bit_length()) # 4 —— 1010需要4位
print((255).bit_length()) # 8 —— 11111111需要8位
print((256).bit_length()) # 9 —— 100000000需要9位
print((0).bit_length()) # 0

2.4 其他进制表示

# Python中的进制表示
binary = 0b1010 # 二进制 (binary)
octal = 0o755 # 八进制 (octal)
decimal = 255 # 十进制 (decimal)
hexadecimal = 0xFF # 十六进制 (hexadecimal)

print(binary, octal, decimal, hexadecimal) # 10 493 255 255

# 转换函数
print(bin(255)) # '0b11111111' 十进制→二进制字符串
print(oct(255)) # '0o377' 十进制→八进制字符串
print(hex(255)) # '0xff' 十进制→十六进制字符串
print(int('0b1111', 2)) # 15 二进制字符串→十进制
print(int('0o17', 8)) # 15 八进制字符串→十进制
print(int('0xf', 16)) # 15 十六进制字符串→十进制

# 格式化输出不同进制
n = 42
print(f"十进制: {n}")
print(f"二进制: {n:b}")
print(f"八进制: {n:o}")
print(f"十六进制: {n:x}")
print(f"二进制(8位): {n:08b}")
print(f"十六进制(大写): {n:X}")

三、Python的位运算符全解

3.1 按位与 & —— 两位都为1才得1

# & 的运算规则(逐位):
# 1 & 1 = 1
# 1 & 0 = 0
# 0 & 1 = 0
# 0 & 0 = 0

a = 0b1100 # 12
b = 0b1010 # 10
# = 0b1000 # 8
print(f"{a:04b}") # 1100
print(f"{b:04b}") # 1010
print(f"{a & b:04b}") # 1000
print(a & b) # 8

# & 的实际应用:判断某一位是否为1
# 检查第2位(从0开始)是否为1
def is_bit_set(n, position):
    """判断n的第position位是否为1"""
    return (n & (1 << position)) != 0

print(is_bit_set(0b1100, 2)) # True —— 1100的第2位是1
print(is_bit_set(0b1100, 0)) # False —— 1100的第0位是0
print(is_bit_set(0b1100, 3)) # True —— 1100的第3位是1

# & 的常用技巧:取低N位(掩码操作)
def low_n_bits(n, num_bits):
    """获取n的低num_bits位"""
    mask = (1 << num_bits) - 1
    return n & mask

print(bin(low_n_bits(0b11010110, 4))) # 0b110 —— 取低4位

3.2 按位或 | —— 任一位为1就得1

# | 的运算规则(逐位):
# 1 | 1 = 1
# 1 | 0 = 1
# 0 | 1 = 1
# 0 | 0 = 0

a = 0b1100 # 12
b = 0b1010 # 10
# | = 0b1110 # 14
print(f"{a:04b}") # 1100
print(f"{b:04b}") # 1010
print(f"{a | b:04b}") # 1110
print(a | b) # 14

# | 的实际应用:设置某一位为1
def set_bit(n, position):
    """将n的第position位设为1"""
    return n | (1 << position)

print(bin(set_bit(0b1000, 1))) # 0b1010 —— 设置了第1位
print(bin(set_bit(0b1000, 2))) # 0b1100 —— 设置了第2位

# | 的常用技巧:合并标志位(权限系统的基础)
READ = 0b001 # 1 —— 读权限
WRITE = 0b010 # 2 —— 写权限
EXECUTE = 0b100 # 4 —— 执行权限

# 赋予读写权限
permission = READ | WRITE
print(f"权限: {permission:03b}") # 011
print(f"权限值: {permission}") # 3

# 追加执行权限
permission |= EXECUTE
print(f"权限: {permission:03b}") # 111
print(f"权限值: {permission}") # 7

3.3 按位异或 ^ —— 两位不同得1,相同得0

# ^ 的运算规则(逐位):
# 1 ^ 1 = 0
# 1 ^ 0 = 1
# 0 ^ 1 = 1
# 0 ^ 0 = 0

a = 0b1100 # 12
b = 0b1010 # 10
# ^ = 0b0110 # 6
print(f"{a:04b}") # 1100
print(f"{b:04b}") # 1010
print(f"{a ^ b:04b}") # 0110
print(a ^ b) # 6

# ^ 的实际应用1:切换某一位(toggle)
def toggle_bit(n, position):
    """翻转n的第position位(1变0,0变1)"""
    return n ^ (1 << position)

x = 0b1010 # 10
print(bin(toggle_bit(x, 0))) # 0b1011 —— 第0位从0变1
print(bin(toggle_bit(x, 1))) # 0b1000 —— 第1位从1变0
print(bin(toggle_bit(x, 3))) # 0b10 —— 第3位从1变0

# ^ 的实际应用2:不使用临时变量交换两个整数
a = 10
b = 20
print(f"交换前: a={a}, b={b}")

a ^= b # a = a ^ b
b ^= a # b = b ^ a = b ^ (a ^ b) = a
a ^= b # a = a ^ b = (a ^ b) ^ a = b
print(f"交换后: a={a}, b={b}")

# 但Python中直接用 a, b = b, a 更优雅!

# ^ 的实际应用3:找出数组中唯一出现奇数次的数
def find_odd_occurrence(arr):
    """在一个数组中,除了一个数出现奇数次,其他都出现偶数次,找出这个数"""
    result = 0
    for num in arr:
        result ^= num # 相同数异或得0,最终只剩出现奇数次的数
    return result

arr = [1, 2, 3, 2, 1, 3, 4, 5, 4]
print(find_odd_occurrence(arr)) # 5

# ^ 的实际应用4:简单的加密/解密
def xor_cipher(text, key):
    """简单的异或加密(对称加密)"""
    return ''.join(chr(ord(c) ^ key) for c in text)

original = "Hello World"
encrypted = xor_cipher(original, 42)
decrypted = xor_cipher(encrypted, 42) # 再次异或同一个key即解密

print(f"原文: {original}")
print(f"加密: {encrypted!r}")
print(f"解密: {decrypted}")

3.4 按位取反 ~ —— 0变1,1变0

# ~ 的运算规则:对每一位取反
# 但在Python中,整数是无限精度的(用补码表示)
# ~n = -(n + 1)

print(~0) # -1
print(~1) # -2
print(~10) # -11
print(~-10) # 9

# 理解:Python使用补码表示负数
# 补码 = 反码 + 1
# ~n 对于正数:-(n + 1)
# ~n 对于负数:-(n + 1)(同样适用)

# 验证
for n in [0, 1, 5, -1, -5, 10, -10]:
    print(f"~{n:>4} = {~n:>4} (预期: {-(n+1):>4})")

# 实际应用:快速计算 -(n+1)
# 虽然不常用,但了解其含义对于理解位运算很重要

# 如果你需要真正按位取反(固定位宽),需要配合掩码
def bitwise_not_fixed(n, num_bits=8):
    """固定位宽的按位取反"""
    mask = (1 << num_bits) - 1
    return (~n) & mask

print(bin(bitwise_not_fixed(0b1100, 8))) # 0b11110011

3.5 左移 << —— 所有位向左移动,右侧补0

# << 左移:所有位向左移动n位,右边补0
# 左移n位 = 乘以 2^n

x = 0b0001 # 1
print(bin(x << 1)) # 0b10 = 2 (= 1 * 2)
print(bin(x << 2)) # 0b100 = 4 (= 1 * 4)
print(bin(x << 3)) # 0b1000 = 8 (= 1 * 8)

# 左移的算术含义:x << n = x * (2 ** n)
for n in range(6):
    print(f"1 << {n} = {1 << n:>3} (2^{n} = {2**n})")

# 实用技巧:快速计算2的幂
print(1 << 0) # 1 = 2^0
print(1 << 1) # 2 = 2^1
print(1 << 10) # 1024 = 2^10
print(1 << 20) # 1048576 = 2^20

# 创建特定位的掩码
BIT_0 = 1 << 0 # 0b0001 = 1
BIT_1 = 1 << 1 # 0b0010 = 2
BIT_2 = 1 << 2 # 0b0100 = 4
BIT_3 = 1 << 3 # 0b1000 = 8

# 大数左移
print(1 << 100) # Python支持任意大的整数!

3.6 右移 >> —— 所有位向右移动,左侧补符号位

# >> 右移:所有位向右移动n位,左侧补符号位(算术右移)
# 右移n位 = 除以 2^n(向下取整)

x = 0b1000 # 8
print(bin(x >> 1)) # 0b100 = 4 (= 8 // 2)
print(bin(x >> 2)) # 0b10 = 2 (= 8 // 4)
print(bin(x >> 3)) # 0b1 = 1 (= 8 // 8)
print(bin(x >> 4)) # 0b0 = 0

# 右移的算术含义:x >> n = x // (2 ** n)
for n in range(5):
    print(f"16 >> {n} = {16 >> n} (16 // {2**n} = {16 // 2**n})")

# 负数右移 —— Python使用算术右移(补符号位)
print(-16 >> 1) # -8
print(-16 >> 2) # -4
print(-15 >> 1) # -8 —— 注意:-15 // 2 = -8(向下取整)

# 快速除以2的幂
print(100 >> 2) # 25 (= 100 // 4)
print(100 >> 3) # 12 (= 100 // 8)
print(100 >> 4) # 6 (= 100 // 16)

# 提取特定位:右移 + 掩码
def get_bits(n, start, count):
    """从n中提取从start位开始的count位"""
    return (n >> start) & ((1 << count) - 1)

# 从0b10110110中提取第3-5位(从0开始)
n = 0b10110110 # 182
# 位: 7 6 5 4 3 2 1 0
# 1 0 1 1 0 1 1 0
# 提取第3-5位(即第3,4,5位:110)
print(bin(get_bits(n, 3, 3))) # 0b110

四、位运算实战:权限系统设计

这是位运算最经典的应用场景之一:

class Permission:
    """基于位运算的权限系统"""
    
    # 定义权限常量(每个权限占一个位)
    READ = 1 << 0 # 0b000001 = 1
    WRITE = 1 << 1 # 0b000010 = 2
    EXECUTE = 1 << 2 # 0b000100 = 4
    DELETE = 1 << 3 # 0b001000 = 8
    ADMIN = 1 << 4 # 0b010000 = 16
    
    @staticmethod
    def has_permission(user_perm, perm):
        """检查是否拥有某项权限"""
        return (user_perm & perm) != 0
    
    @staticmethod
    def grant(user_perm, perm):
        """授予权限"""
        return user_perm | perm
    
    @staticmethod
    def revoke(user_perm, perm):
        """撤销权限"""
        return user_perm & (~perm)
    
    @staticmethod
    def toggle(user_perm, perm):
        """切换权限"""
        return user_perm ^ perm
    
    @staticmethod
    def permission_names(perm_value):
        """将权限值转换为权限名列表"""
        names = []
        for name in ['READ', 'WRITE', 'EXECUTE', 'DELETE', 'ADMIN']:
            if perm_value & getattr(Permission, name):
                names.append(name)
        return names

# 使用演示
user1_perm = Permission.READ | Permission.WRITE # 读写权限 = 3
print(f"初始权限: {Permission.permission_names(user1_perm)}")

# 检查权限
print(f"有读权限: {Permission.has_permission(user1_perm, Permission.READ)}")
print(f"有删除权限: {Permission.has_permission(user1_perm, Permission.DELETE)}")

# 授予执行权限
user1_perm = Permission.grant(user1_perm, Permission.EXECUTE)
print(f"授予EXECUTE后: {Permission.permission_names(user1_perm)}")

# 撤销写权限
user1_perm = Permission.revoke(user1_perm, Permission.WRITE)
print(f"撤销WRITE后: {Permission.permission_names(user1_perm)}")

# 切换管理员权限
user1_perm = Permission.toggle(user1_perm, Permission.ADMIN)
print(f"切换ADMIN后: {Permission.permission_names(user1_perm)}")

五、位运算实战:颜色处理

def rgb_to_hex(r, g, b):
    """RGB颜色值转换为十六进制颜色码"""
    # 方式1:位运算
    return f"#{(r << 16) | (g << 8) | b:06X}"

# 等价操作:
# 红色分量左移16位: r << 16
# 绿色分量左移8位: g << 8
# 蓝色分量不移动: b
# 三者按位或合并

print(rgb_to_hex(255, 128, 0)) # #FF8000
print(rgb_to_hex(0, 255, 0)) # #00FF00
print(rgb_to_hex(52, 152, 219)) # #3498DB
print(rgb_to_hex(255, 255, 255)) # #FFFFFF

def hex_to_rgb(hex_color):
    """十六进制颜色码转换为RGB值"""
    hex_color = hex_color.lstrip('#')
    value = int(hex_color, 16)
    
    # 提取各分量
    r = (value >> 16) & 0xFF
    g = (value >> 8) & 0xFF
    b = value & 0xFF
    
    return (r, g, b)

print(hex_to_rgb("#FF8000")) # (255, 128, 0)
print(hex_to_rgb("#3498DB")) # (52, 152, 219)

# 颜色混合(简单平均)
def blend_colors(color1, color2, ratio=0.5):
    """混合两种颜色"""
    r1, g1, b1 = color1
    r2, g2, b2 = color2
    
    r = int(r1 * (1 - ratio) + r2 * ratio)
    g = int(g1 * (1 - ratio) + g2 * ratio)
    b = int(b1 * (1 - ratio) + b2 * ratio)
    
    return (r, g, b)

# 颜色变亮/变暗
def brighten(color, factor=1.2):
    """提亮颜色"""
    r, g, b = color
    r = min(255, int(r * factor))
    g = min(255, int(g * factor))
    b = min(255, int(b * factor))
    return (r, g, b)

def darken(color, factor=0.8):
    """变暗颜色"""
    r, g, b = color
    r = max(0, int(r * factor))
    g = max(0, int(g * factor))
    b = max(0, int(b * factor))
    return (r, g, b)

base_color = (100, 150, 200)
print(f"原色: {base_color}")
print(f"提亮: {brighten(base_color)}")
print(f"变暗: {darken(base_color)}")

六、位运算实战:状态标记与位图

class UserStatus:
    """用户状态标记系统(用一个整数表示多种状态)"""
    
    ONLINE = 1 << 0 # 在线
    VERIFIED = 1 << 1 # 已验证
    PREMIUM = 1 << 2 # 会员
    BANNED = 1 << 3 # 被封禁
    MODERATOR = 1 << 4 # 版主
    
    @classmethod
    def is_online(cls, status):
        return (status & cls.ONLINE) != 0
    
    @classmethod
    def set_online(cls, status):
        return status | cls.ONLINE
    
    @classmethod
    def set_offline(cls, status):
        return status & (~cls.ONLINE)
    
    @classmethod
    def describe(cls, status):
        """描述用户状态"""
        labels = []
        for attr in ['ONLINE', 'VERIFIED', 'PREMIUM', 'BANNED', 'MODERATOR']:
            flag = getattr(cls, attr)
            if status & flag:
                labels.append(attr)
        return labels if labels else ['NONE']

# 批量处理用户状态的位图
class UserBitmap:
    """使用位图追踪大量用户的在线状态"""
    
    def __init__(self, max_users=1024):
        # 每个整数存储64个用户的位
        self.bitmap_size = (max_users + 63) // 64
        self.bitmap = [0] * self.bitmap_size
    
    def set_online(self, user_id):
        """设置用户在线"""
        word_idx = user_id // 64 # 在哪个整数
        bit_idx = user_id % 64 # 在那个整数的哪一位
        self.bitmap[word_idx] |= (1 << bit_idx)
    
    def set_offline(self, user_id):
        """设置用户离线"""
        word_idx = user_id // 64
        bit_idx = user_id % 64
        self.bitmap[word_idx] &= ~(1 << bit_idx)
    
    def is_online(self, user_id):
        """检查用户是否在线"""
        word_idx = user_id // 64
        bit_idx = user_id % 64
        return (self.bitmap[word_idx] & (1 << bit_idx)) != 0
    
    def online_count(self):
        """在线用户总数(利用位运算快速统计)"""
        total = 0
        for word in self.bitmap:
            total += word.bit_count() # Python 3.8+的bit_count方法
        return total

# 使用
bitmap = UserBitmap(1024)
bitmap.set_online(1)
bitmap.set_online(100)
bitmap.set_online(500)
print(f"用户1在线: {bitmap.is_online(1)}")
print(f"用户2在线: {bitmap.is_online(2)}")
print(f"在线总数: {bitmap.online_count()}")

七、位运算的性能优势

import timeit

# 乘除2的幂 vs 移位
n = 1234567890

# 乘法 vs 左移
t_multiply = timeit.timeit(lambda: n * 64, number=10_000_000)
t_shift = timeit.timeit(lambda: n << 6, number=10_000_000)

print(f"n * 64: {t_multiply:.4f}s")
print(f"n << 6: {t_shift:.4f}s")
print(f"移位比乘法快: {t_multiply / t_shift:.1f}x")

# 除法 vs 右移
t_pide = timeit.timeit(lambda: n // 64, number=10_000_000)
t_rshift = timeit.timeit(lambda: n >> 6, number=10_000_000)

print(f"n // 64: {t_pide:.4f}s")
print(f"n >> 6: {t_rshift:.4f}s")
print(f"移位比除法快: {t_pide / t_rshift:.1f}x")

# 取模2的幂 vs 位与
t_modulo = timeit.timeit(lambda: n % 64, number=10_000_000)
t_bitand = timeit.timeit(lambda: n & 63, number=10_000_000)

print(f"n % 64: {t_modulo:.4f}s")
print(f"n & 63: {t_bitand:.4f}s")
print(f"位与比取模快: {t_modulo / t_bitand:.1f}x")

# 奇偶判断
t_mod2 = timeit.timeit(lambda: n % 2 == 0, number=10_000_000)
t_and1 = timeit.timeit(lambda: n & 1 == 0, number=10_000_000)

print(f"n % 2 == 0: {t_mod2:.4f}s")
print(f"n & 1 == 0: {t_and1:.4f}s")
print(f"位与比取模快: {t_mod2 / t_and1:.1f}x")

八、位运算的常用技巧速查

# ===== 位运算常用技巧 =====

# 1. 判断奇偶
def is_even(n):
    return (n & 1) == 0
def is_odd(n):
    return (n & 1) == 1

# 2. 乘以/除以 2 的幂
mul_8 = n << 3 # n * 8
p_8 = n >> 3 # n // 8
mod_8 = n & 7 # n % 8

# 3. 获取/设置/清除第k位
def get_kth_bit(n, k):
    return (n >> k) & 1

def set_kth_bit(n, k):
    return n | (1 << k)

def clear_kth_bit(n, k):
    return n & ~(1 << k)

# 4. 清除最低位的1
def clear_lowest_set_bit(n):
    """清除最低位的1(Brian Kernighan算法)"""
    return n & (n - 1)

# 5. 获取最低位的1
def get_lowest_set_bit(n):
    return n & (-n)

# 6. 统计二进制中1的个数
def count_ones(n):
    # Python 3.8+直接用 int.bit_count()
    return n.bit_count()
    # 手动方法:
    # count = 0
    # while n:
    # n &= n - 1
    # count += 1
    # return count

# 7. 判断是否为2的幂
def is_power_of_two(n):
    return n > 0 and (n & (n - 1)) == 0

# 8. 将最低位的0变为1
def set_lowest_zero_bit(n):
    return n | (n + 1)

# 验证
print(is_even(10)) # True
print(is_odd(10)) # False
print(get_kth_bit(0b1010, 3)) # 1
print(set_kth_bit(0b1000, 1)) # 10 (0b1010)
print(clear_kth_bit(0b1111, 1)) # 13 (0b1101)
print(clear_lowest_set_bit(0b1100)) # 8 (0b1000)
print(get_lowest_set_bit(0b1100)) # 4 (0b100)
print(count_ones(0b10110110)) # 5
print(is_power_of_two(16)) # True
print(is_power_of_two(18)) # False

九、实战案例:IP地址与子网掩码计算

class IPCalculator:
    """IP地址与子网掩码计算工具"""
    
    @staticmethod
    def ip_to_int(ip_str):
        """IP地址字符串转整数"""
        parts = ip_str.split('.')
        ip_int = 0
        for part in parts:
            ip_int = (ip_int << 8) | int(part)
        return ip_int
    
    @staticmethod
    def int_to_ip(ip_int):
        """整数转IP地址字符串"""
        parts = []
        for i in range(4):
            parts.append(str((ip_int >> (24 - i * 8)) & 0xFF))
        return '.'.join(parts)
    
    @staticmethod
    def get_network_address(ip, subnet_mask):
        """计算网络地址"""
        ip_int = IPCalculator.ip_to_int(ip)
        mask_int = IPCalculator.ip_to_int(subnet_mask)
        network_int = ip_int & mask_int
        return IPCalculator.int_to_ip(network_int)
    
    @staticmethod
    def get_broadcast_address(ip, subnet_mask):
        """计算广播地址"""
        ip_int = IPCalculator.ip_to_int(ip)
        mask_int = IPCalculator.ip_to_int(subnet_mask)
        # 广播地址 = 网络地址 | (~掩码 的低32位)
        broadcast_int = (ip_int & mask_int) | (~mask_int & 0xFFFFFFFF)
        return IPCalculator.int_to_ip(broadcast_int)
    
    @staticmethod
    def get_host_count(subnet_mask):
        """计算可用主机数"""
        mask_int = IPCalculator.ip_to_int(subnet_mask)
        # 主机数 = 2^(32-前缀长度) - 2
        prefix_len = mask_int.bit_count()
        return (1 << (32 - prefix_len)) - 2
    
    @staticmethod
    def is_same_network(ip1, ip2, subnet_mask):
        """判断两个IP是否在同一子网"""
        return IPCalculator.get_network_address(ip1, subnet_mask) ==
               IPCalculator.get_network_address(ip2, subnet_mask)

# 使用演示
ip = "192.168.1.100"
mask = "255.255.255.0"

print(f"IP地址: {ip}")
print(f"子网掩码: {mask}")
print(f"IP整数: {IPCalculator.ip_to_int(ip)}")
print(f"网络地址: {IPCalculator.get_network_address(ip, mask)}")
print(f"广播地址: {IPCalculator.get_broadcast_address(ip, mask)}")
print(f"可用主机数: {IPCalculator.get_host_count(mask)}")

ip2 = "192.168.1.200"
print(f"{ip} 与 {ip2} 在同一子网: "
      f"{IPCalculator.is_same_network(ip, ip2, mask)}")

ip3 = "192.168.2.1"
print(f"{ip} 与 {ip3} 在同一子网: "
      f"{IPCalculator.is_same_network(ip, ip3, mask)}")

十、本章小结

本文我们从二进制基础开始,系统学习了Python的所有位运算符:

  1. 按位与 &:两位都为1才是1。常用来位检查、掩码操作、权限验证。
  2. 按位或 |:任一位为1就是1。常用来位设置、标志合同时。
  3. 按位异或 ^:两位不同得1。常用来位翻转、无临时变量交换、找奇数次出现的数。
  4. 按位取反 ~:~n = -(n+1)。Python中用补码表示。
  5. 左移 <<:n << k = n * 2^k。常用来更快乘法、新建掩码。
  6. 右移 >>:n >> k = n // 2^k。常用来更快除法、提取位。
  7. 实战应用:权限系统、颜色处理、状态标记、IP地址计算——位运算在这些场景中简洁高效。

在这个场景下,位运算虽然看起来"底层",但掌握它意味着你能写出更高效的代码,也能更好地理解计算机的工作原理。当你看到permission & READ这样的代码时,你不再困惑,而是会心一笑——这就是位运算的魅力。

实际处理时,总的来说,Python位运算符适合结合实际项目边做边理解。先抓住核心思路,再逐步补上细节和边界处理,最后效果会更稳定,也更容易复用。

相关资讯
点击查看更多
游戏推荐
推荐专题
热门阅读
推荐下载