hasattr():属性检查的"安全检查员"
1. 基础用法:安全检查对象属性
hasattr()函数用于检查对象是否具有指定名称的属性,返回布尔值。
class UserProfile:
def __init__(self, name, email):
self.name = name
self.email = email
self._internal_id = 1001
def get_info(self):
return f"{self.name} ({self.email})"
# 创建对象实例
user = UserProfile("张三", "zhang@example.com")
# 检查属性是否存在
print(f"是否有name属性: {hasattr(user, 'name')}") # 输出: True
print(f"是否有age属性: {hasattr(user, 'age')}") # 输出: False
print(f"是否有内部属性: {hasattr(user, '_internal_id')}") # 输出: True
print(f"是否有方法: {hasattr(user, 'get_info')}") # 输出: True
# 等价于手动实现
def manual_hasattr(obj, attr_name):
try:
getattr(obj, attr_name)
return True
except AttributeError:
return False
print(f"手动实现验证: {manual_hasattr(user, 'name') == hasattr(user, 'name')}")
2. 实际应用:动态API兼容性检查
class PluginSystem:
def __init__(self):
self.plugins = []
def register_plugin(self, plugin):
"""注册插件,检查必需接口"""
required_methods = ['execute', 'get_version', 'get_name']
# 检查插件是否实现所有必需方法
missing_methods = [method for method in required_methods
if not hasattr(plugin, method)]
if missing_methods:
print(f"插件缺少必要方法: {missing_methods}")
return False
self.plugins.append(plugin)
print(f"插件注册成功: {plugin.get_name()}")
return True
def safe_plugin_execution(self, plugin_name, *args):
"""安全执行插件方法"""
plugin = next((p for p in self.plugins if hasattr(p, 'get_name') and
p.get_name() == plugin_name), None)
if not plugin:
return f"插件未找到: {plugin_name}"
if hasattr(plugin, 'validate_input'):
if not plugin.validate_input(*args):
return "输入验证失败"
if hasattr(plugin, 'execute'):
return plugin.execute(*args)
return "插件缺少execute方法"
class BasePlugin:
def get_name(self):
return "基础插件"
def get_version(self):
return "1.0"
def execute(self, *args):
return "基础执行"
class AdvancedPlugin(BasePlugin):
def get_name(self):
return "高级插件"
def validate_input(self, *args):
return len(args) > 0
def pre_process(self, data):
return f"预处理: {data}"
# 使用示例
system = PluginSystem()
# 注册插件
base_plugin = BasePlugin()
advanced_plugin = AdvancedPlugin()
print("注册基础插件:", system.register_plugin(base_plugin))
print("注册高级插件:", system.register_plugin(advanced_plugin))
# 安全执行
result1 = system.safe_plugin_execution("高级插件", "测试数据")
print("执行结果:", result1)
result2 = system.safe_plugin_execution("不存在的插件")
print("执行结果:", result2)
hash():对象哈希的"数字指纹"
1. 基础用法:计算对象哈希值
hash()函数返回对象的哈希值(整数),主要用于字典键的快速查找和比较。相同值的对象应该有相同的哈希值。
# 基本数据类型的哈希值
print(f"整数哈希: {hash(42)}") # 输出: 42
print(f"浮点数哈希: {hash(3.14)}") # 输出: 322818021289917443
print(f"字符串哈希: {hash('hello')}") # 输出: 如: -8044241058694013083
print(f"布尔值哈希: {hash(True)}") # 输出: 1
# 相同值的不同类型可能有相同哈希值
print(f"1和1.0哈希相同: {hash(1) == hash(1.0)}") # 输出: True
# 不可变类型的哈希
tuple_hash = hash((1, 2, 3))
print(f"元组哈希: {tuple_hash}")
# 注意:可变类型(如列表)不能哈希
try:
list_hash = hash([1, 2, 3])
except TypeError as e:
print(f"列表哈希错误: {e}")
2. 实际应用:自定义对象的哈希实现
class Person:
def __init__(self, name, age, email):
self.name = name
self.age = age
self.email = email
self._hash_cache = None
def __eq__(self, other):
"""定义相等性比较"""
if not isinstance(other, Person):
return False
return (self.name, self.age, self.email) == (other.name, other.age, other.email)
def __hash__(self):
"""自定义哈希计算"""
if self._hash_cache is None:
# 基于不可变属性计算哈希
self._hash_cache = hash((self.name, self.age, self.email))
return self._hash_cache
def __repr__(self):
return f"Person('{self.name}', {self.age}, '{self.email}')"
class CustomDict:
"""基于哈希的简单字典实现"""
def __init__(self):
self._buckets = [[] for _ in range(8)]
self._size = 0
def _get_bucket_index(self, key):
return hash(key) % len(self._buckets)
def __setitem__(self, key, value):
bucket_index = self._get_bucket_index(key)
bucket = self._buckets[bucket_index]
for i, (k, v) in enumerate(bucket):
if k == key:
bucket[i] = (key, value)
return
bucket.append((key, value))
self._size += 1
# 简单的扩容机制
if self._size > len(self._buckets) * 0.7:
self._resize()
def __getitem__(self, key):
bucket_index = self._get_bucket_index(key)
bucket = self._buckets[bucket_index]
for k, v in bucket:
if k == key:
return v
raise KeyError(key)
def _resize(self):
old_buckets = self._buckets
self._buckets = [[] for _ in range(len(old_buckets) * 2)]
self._size = 0
for bucket in old_buckets:
for key, value in bucket:
self[key] = value
def __contains__(self, key):
try:
self[key]
return True
except KeyError:
return False
# 使用示例
# 创建自定义对象
person1 = Person("张三", 25, "zhang@example.com")
person2 = Person("李四", 30, "li@example.com")
person3 = Person("张三", 25, "zhang@example.com") # 与person1相同
print(f"person1哈希: {hash(person1)}")
print(f"person2哈希: {hash(person2)}")
print(f"person3哈希: {hash(person3)}")
print(f"person1 == person3: {person1 == person3}")
print(f"hash(person1) == hash(person3): {hash(person1) == hash(person3)}")
# 在字典中使用自定义对象
person_dict = {person1: "第一人", person2: "第二人"}
print(f"字典查找person1: {person_dict[person1]}")
print(f"字典查找person3: {person_dict[person3]}") # 应该找到person1的值
# 测试自定义字典
custom_dict = CustomDict()
custom_dict["key1"] = "value1"
custom_dict[42] = "数字值"
custom_dict[person1] = "人员对象"
print(f"自定义字典查找: {custom_dict['key1']}")
print(f"包含检查: {'key1' in custom_dict}")
print(f"人员查找: {custom_dict[person1]}")
help():交互式帮助的"知识库"
1. 基础用法:获取对象帮助信息
help()函数启动Python的内置帮助系统,可以查看模块、函数、类、方法等的文档字符串。
# 无参数调用:进入交互式帮助系统
# help()
# 查看内置函数的帮助
print("=== len函数帮助 ===")
help(len) # 显示len函数的帮助信息
print("\n=== list类帮助 ===")
help(list) # 显示list类的帮助信息
# 查看当前模块的帮助
import math
print("\n=== math模块帮助 ===")
help(math) # 显示math模块的帮助信息
# 查看自定义对象的帮助
class Calculator:
"""一个简单的计算器类"""
def add(self, a, b):
"""返回两个数的和"""
return a + b
def multiply(self, a, b):
"""返回两个数的积"""
return a * b
print("\n=== 自定义类帮助 ===")
help(Calculator) # 显示自定义类的帮助
# 使用字符串搜索帮助
print("\n=== 搜索帮助 ===")
help("list.append") # 搜索特定主题的帮助
2. 实际应用:开发中的实时文档查看
class DevelopmentHelper:
def __init__(self):
self.recent_objects = []
def inspect_object(self, obj):
"""检查对象并提供帮助信息"""
obj_type = type(obj).__name__
print(f"=== 检查 {obj_type} 对象 ===")
# 显示基本帮助
help(obj)
# 显示所有可用方法
print(f"\n=== {obj_type} 的可用方法 ===")
methods = [method for method in dir(obj)
if callable(getattr(obj, method)) and not method.startswith('_')]
for method in methods[:10]: # 只显示前10个方法
print(f"- {method}")
self.recent_objects.append(obj)
return methods
def compare_objects(self, obj1, obj2):
"""比较两个对象的帮助信息"""
print("=== 对象比较 ===")
obj1_methods = set(dir(obj1))
obj2_methods = set(dir(obj2))
common_methods = obj1_methods.intersection(obj2_methods)
unique_to_obj1 = obj1_methods - obj2_methods
unique_to_obj2 = obj2_methods - obj1_methods
print(f"共同方法数量: {len(common_methods)}")
print(f"obj1独有方法: {len(unique_to_obj1)}")
print(f"obj2独有方法: {len(unique_to_obj2)}")
return common_methods, unique_to_obj1, unique_to_obj2
def get_function_signature(self, func):
"""获取函数的签名信息"""
try:
import inspect
signature = inspect.signature(func)
return str(signature)
except:
return "无法获取签名"
# 使用示例
helper = DevelopmentHelper()
# 检查常见对象
print("检查字符串对象:")
helper.inspect_object("hello")
print("\n检查列表对象:")
helper.inspect_object([])
# 比较不同对象
list_obj = []
dict_obj = {}
common, unique_list, unique_dict = helper.compare_objects(list_obj, dict_obj)
print(f"\n列表和字典的共同方法示例: {list(common)[:5]}")
print(f"列表独有方法示例: {list(unique_list)[:3]}")
print(f"字典独有方法示例: {list(unique_dict)[:3]}")
# 自定义帮助函数
def custom_help(topic):
"""增强的帮助函数"""
if topic == "快捷键":
print("""
常用帮助快捷键:
- q: 退出帮助
- 空格: 下一页
- 回车: 下一行
- b: 上一页
""")
elif topic == "调试":
print("""
调试帮助:
- 使用 help(对象) 查看对象文档
- 使用 dir(对象) 查看所有属性
- 使用 type(对象) 查看对象类型
""")
else:
help(topic)
# 测试自定义帮助
print("\n=== 自定义帮助 ===")
custom_help("快捷键")
hex():十六进制转换的"翻译器"
1. 基础用法:整数转十六进制字符串
hex()函数将整数转换为带有"0x"前缀的小写十六进制字符串。
# 基本转换
print(f"255的十六进制: {hex(255)}") # 输出: '0xff'
print(f"-42的十六进制: {hex(-42)}") # 输出: '-0x2a'
print(f"0的十六进制: {hex(0)}") # 输出: '0x0'
# 大整数转换
large_number = 2**64
print(f"2^64的十六进制: {hex(large_number)}")
# 其他进制表示对比
number = 255
print(f"十进制: {number}")
print(f"十六进制: {hex(number)}")
print(f"八进制: {oct(number)}")
print(f"二进制: {bin(number)}")
# 自定义__index__方法的对象
class CustomNumber:
def __index__(self):
return 100
custom_obj = CustomNumber()
print(f"自定义对象转换: {hex(custom_obj)}") # 输出: '0x64'
2. 实际应用:颜色值和内存地址处理
class ColorConverter:
@staticmethod
def rgb_to_hex(red, green, blue):
"""将RGB颜色转换为十六进制"""
if not all(0 <= x <= 255 for x in (red, green, blue)):
raise ValueError("RGB值必须在0-255范围内")
hex_color = f"#{red:02x}{green:02x}{blue:02x}"
return hex_color.upper()
@staticmethod
def hex_to_rgb(hex_color):
"""将十六进制颜色转换为RGB"""
hex_color = hex_color.lstrip('#')
if len(hex_color) == 3:
hex_color = ''.join(c * 2 for c in hex_color)
if len(hex_color) != 6:
raise ValueError("十六进制颜色格式不正确")
red = int(hex_color[0:2], 16)
green = int(hex_color[2:4], 16)
blue = int(hex_color[4:6], 16)
return red, green, blue
@staticmethod
def format_hex(number, prefix=True, uppercase=True, width=None):
"""格式化十六进制输出"""
if prefix:
hex_str = hex(number)
else:
hex_str = format(number, 'x')
if uppercase:
hex_str = hex_str.upper()
if width is not None:
# 移除前缀后填充宽度
if prefix and hex_str.startswith('0X'):
hex_str = '0X' + hex_str[2:].zfill(width)
elif prefix and hex_str.startswith('-0X'):
hex_str = '-0X' + hex_str[3:].zfill(width)
elif hex_str.startswith('-'):
hex_str = '-' + hex_str[1:].zfill(width)
else:
hex_str = hex_str.zfill(width)
return hex_str
class MemoryAddressHelper:
@staticmethod
def get_object_address(obj):
"""获取对象的内存地址(十六进制)"""
address = id(obj)
return hex(address)
@staticmethod
def format_memory_dump(data, bytes_per_line=16):
"""格式化内存转储(类似hexdump)"""
result = []
for i in range(0, len(data), bytes_per_line):
chunk = data[i:i + bytes_per_line]
# 地址部分
address_hex = hex(i)[2:].zfill(8)
# 十六进制部分
hex_part = ' '.join(f"{b:02x}" for b in chunk)
hex_part = hex_part.ljust(bytes_per_line * 3 - 1)
# ASCII部分
ascii_part = ''.join(chr(b) if 32 <= b <= 126 else '.' for b in chunk)
result.append(f"{address_hex}: {hex_part} {ascii_part}")
return '\n'.join(result)
# 使用示例
converter = ColorConverter()
# 颜色转换
print("=== 颜色转换示例 ===")
rgb_color = (255, 128, 64)
hex_color = converter.rgb_to_hex(*rgb_color)
print(f"RGB{rgb_color} -> {hex_color}")
converted_rgb = converter.hex_to_rgb(hex_color)
print(f"{hex_color} -> RGB{converted_rgb}")
# 十六进制格式化
print("\n=== 十六进制格式化 ===")
test_number = 255
print(f"默认: {hex(test_number)}")
print(f"无前缀: {converter.format_hex(test_number, prefix=False)}")
print(f"大写: {converter.format_hex(test_number, uppercase=True)}")
print(f"宽度8: {converter.format_hex(test_number, width=8)}")
# 内存地址示例
print("\n=== 内存地址示例 ===")
memory_helper = MemoryAddressHelper()
sample_list = [1, 2, 3, 4, 5]
print(f"列表内存地址: {memory_helper.get_object_address(sample_list)}")
# 模拟内存转储
sample_data = bytes(range(256))
dump_output = memory_helper.format_memory_dump(sample_data[:64]) # 只显示前64字节
print("\n内存转储示例:")
print(dump_output)
# 浮点数十六进制表示
print("\n=== 浮点数十六进制 ===")
float_number = 3.14159
print(f"浮点数{float_number}的十六进制: {float_number.hex()}")
总结
本章解析了Python中四个重要的内置函数:
- 1. hasattr(object, name) - 属性检查的安全检查员
- 2. hash(object) - 对象哈希值的数字指纹
- 3. help([object]) - 交互式帮助的知识库
- 4. hex(integer) - 十六进制转换的翻译器
关键知识点总结:
- •
hasattr()通过尝试getattr()并捕获AttributeError来实现属性检查 - •
hash()返回对象的哈希值,用于快速比较和字典键查找 - •
help()提供交互式帮助系统,可查看各种对象的文档 - •
hex()将整数转换为带"0x"前缀的十六进制字符串
版本兼容性提醒:
- • 在Python 3.4+中,
help()函数的签名信息更加全面和一致 - •
hash()会根据宿主机的字长截断自定义对象的返回值 - •
hex()支持定义__index__()方法的自定义对象
这四个函数虽然看似简单,但它们是Python动态特性和元编程能力的重要体现。掌握它们的正确用法可以帮助开发者编写出更加健壮、灵活和高效的代码,特别是在框架开发、库设计和工具构建等高级应用场景中。