本文目录导读:

我来为你提供一个完整的Python版本兼容工具封装案例,涵盖常见的兼容性场景:
基础版本兼容装饰器
# version_compat.py
import sys
import functools
from typing import Any, Callable, TypeVar, Tuple
F = TypeVar('F', bound=Callable[..., Any])
class VersionCompat:
"""版本兼容工具类"""
@staticmethod
def python_version():
"""获取Python版本信息"""
return {
'major': sys.version_info.major,
'minor': sys.version_info.minor,
'micro': sys.version_info.micro,
'releaselevel': sys.version_info.releaselevel,
'serial': sys.version_info.serial
}
@staticmethod
def version_compare(min_version: str) -> bool:
"""比较当前版本是否满足最低版本要求"""
current = sys.version_info[:2]
required = tuple(map(int, min_version.split('.')))
return current >= required
# 版本要求装饰器
def requires_version(min_version: str):
"""装饰器:要求最低Python版本"""
def decorator(func: F) -> F:
@functools.wraps(func)
def wrapper(*args, **kwargs):
if not VersionCompat.version_compare(min_version):
raise RuntimeError(
f"需要Python {min_version}+,当前版本: "
f"{'.'.join(map(str, sys.version_info[:3]))}"
)
return func(*args, **kwargs)
return wrapper # type: ignore
return decorator
# 多版本支持装饰器
def version_dispatcher(version_map: dict):
"""根据版本分发到不同实现"""
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
current_ver = f"{sys.version_info.major}.{sys.version_info.minor}"
# 查找最匹配的版本
matched_ver = None
for ver in version_map:
if current_ver.startswith(ver):
matched_ver = ver
break
if matched_ver:
return version_map[matched_ver](*args, **kwargs)
return func(*args, **kwargs)
return wrapper
return decorator
具体兼容性实现示例
# compat_implementations.py
from version_compat import requires_version, version_dispatcher, VersionCompat
import sys
from typing import List, Any, Union
class StringIOCompat:
"""StringIO版本兼容封装"""
@staticmethod
def create_stringio():
"""创建StringIO对象"""
if sys.version_info.major == 2:
from StringIO import StringIO # Python 2
else:
from io import StringIO # Python 3+
return StringIO()
class ConfigParserCompat:
"""ConfigParser版本兼容封装"""
@staticmethod
def create_parser():
"""创建ConfigParser对象"""
if sys.version_info.major == 2:
from ConfigParser import SafeConfigParser
return SafeConfigParser()
else:
import configparser
# Python 3.2+ 使用 ConfigParser
return configparser.ConfigParser()
class UnicodeCompat:
"""Unicode处理版本兼容"""
@staticmethod
def is_str(obj: Any) -> bool:
"""检查是否为字符串"""
if sys.version_info.major == 2:
return isinstance(obj, (str, unicode)) # noqa: F821
return isinstance(obj, str)
@staticmethod
def to_unicode(text: Union[str, bytes], encoding: str = 'utf-8') -> str:
"""转换为Unicode字符串"""
if sys.version_info.major == 2:
if isinstance(text, str):
return text.decode(encoding)
return text
else:
if isinstance(text, bytes):
return text.decode(encoding)
return text
class ItertoolsCompat:
"""itertools工具版本兼容"""
@staticmethod
def zip_longest(*iterables, fillvalue=None):
"""兼容版本的zip_longest"""
if sys.version_info.major == 2:
from itertools import izip_longest
return izip_longest(*iterables, fillvalue=fillvalue)
else:
from itertools import zip_longest
return zip_longest(*iterables, fillvalue=fillvalue)
@staticmethod
def accumulate(iterable, func=None):
"""兼容版本的accumulate (Python 3.2+)"""
if sys.version_info >= (3, 2):
from itertools import accumulate
return accumulate(iterable, func)
else:
# 手动实现
result = []
iterator = iter(iterable)
try:
total = next(iterator)
except StopIteration:
return
result.append(total)
for element in iterator:
total = func(total, element) if func else total + element
result.append(total)
return result
高级封装类
# advanced_compat.py
import sys
import inspect
from typing import Any, Dict, Optional, Callable
from functools import wraps
class AdvancedVersionCompat:
"""高级版本兼容封装"""
def __init__(self):
self._compat_map: Dict[str, Any] = {}
self._rules: list = []
def register(self, name: str,
min_version: Optional[str] = None,
max_version: Optional[str] = None,
exact_version: Optional[str] = None):
"""注册兼容实现"""
def decorator(func: Callable) -> Callable:
@wraps(func)
def wrapper(*args, **kwargs):
# 检查版本条件
if min_version and not self._check_min_version(min_version):
raise VersionError(f"需要Python {min_version}+")
if max_version and self._check_min_version(max_version):
raise VersionError(f"仅支持Python {max_version}以下")
if exact_version and not self._check_exact_version(exact_version):
raise VersionError(f"需要精确的Python {exact_version}")
return func(*args, **kwargs)
self._compat_map[name] = wrapper
return wrapper
return decorator
def _check_min_version(self, version: str) -> bool:
"""检查最低版本"""
current = sys.version_info[:2]
required = tuple(map(int, version.split('.')))
return current >= required
def _check_exact_version(self, version: str) -> bool:
"""检查精确版本"""
current = f"{sys.version_info.major}.{sys.version_info.minor}"
return current == version
def get_implementation(self, name: str) -> Optional[Callable]:
"""获取兼容实现"""
return self._compat_map.get(name)
def add_rule(self, condition: Callable,
action: Callable,
version_specific: bool = False):
"""添加兼容规则"""
self._rules.append({
'condition': condition,
'action': action,
'version_specific': version_specific
})
class VersionError(Exception):
"""版本错误异常"""
pass
class CompatibleDict(dict):
"""兼容性字典"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._version_map = {}
def set_version_value(self, key: str, value: Any,
min_version: str = '0.0',
max_version: str = '99.99'):
"""设置版本特定值"""
if key not in self._version_map:
self._version_map[key] = []
self._version_map[key].append({
'value': value,
'min_version': tuple(map(int, min_version.split('.'))),
'max_version': tuple(map(int, max_version.split('.')))
})
def __getitem__(self, key):
"""获取适合当前版本的值"""
if key in self._version_map:
current = sys.version_info[:2]
for entry in self._version_map[key]:
if entry['min_version'] <= current <= entry['max_version']:
return entry['value']
return super().__getitem__(key)
使用示例
# usage_example.py
from version_compat import requires_version, version_dispatcher
from compat_implementations import StringIOCompat, UnicodeCompat
from advanced_compat import AdvancedVersionCompat, CompatibleDict
# 1. 使用版本要求装饰器
@requires_version('3.6')
def modern_feature():
"""需要Python 3.6+的特性"""
print("使用f-string")
name = "World"
return f"Hello, {name}!"
# 2. 版本分发
@version_dispatcher({
'2.7': lambda x: f"Python 2.7: {x}",
'3.6': lambda x: f"Python 3.6+: {x}"
})
def process_data(data):
return f"默认处理: {data}"
# 3. 使用兼容工具类
def write_to_string():
"""使用兼容的StringIO"""
buffer = StringIOCompat.create_stringio()
buffer.write("Hello, Compatibility!")
return buffer.getvalue()
# 4. 使用高级兼容器
compat = AdvancedVersionCompat()
@compat.register('process_data', min_version='3.6')
def modern_processor(data):
return data.upper()
@compat.register('process_data', max_version='2.7')
def legacy_processor(data):
return data.upper() + " (legacy)"
# 5. 使用兼容字典
compat_dict = CompatibleDict()
compat_dict['default'] = "默认值"
compat_dict.set_version_value('api_url', 'http://api.legacy.com',
min_version='2.7', max_version='3.5')
compat_dict.set_version_value('api_url', 'http://api.modern.com',
min_version='3.6', max_version='99.99')
# 测试
if __name__ == "__main__":
print(f"Python版本: {'.'.join(map(str, sys.version_info[:3]))}")
try:
result = modern_feature()
print(f"Modern feature: {result}")
except RuntimeError as e:
print(f"版本不兼容: {e}")
# 测试版本分发
print(process_data("test data"))
# 测试StringIO
string_content = write_to_string()
print(f"StringIO内容: {string_content}")
# 测试兼容字典
print(f"API URL: {compat_dict['api_url']}")
项目集成示例
# project_integration.py
from typing import Any, Dict, Optional
import sys
import json
class CompatibleProject:
"""兼容性项目封装示例"""
def __init__(self, config_path: Optional[str] = None):
self.config = self._load_config(config_path)
self._init_compat_layer()
def _load_config(self, config_path: Optional[str]) -> Dict[str, Any]:
"""加载配置"""
default_config = {
'encoding': 'utf-8',
'use_new_features': False
}
if config_path:
try:
with open(config_path, 'r') as f:
loaded = json.load(f)
default_config.update(loaded)
except Exception:
pass
return default_config
def _init_compat_layer(self):
"""初始化兼容层"""
self.compat = AdvancedVersionCompat()
# 注册兼容方法
@self.compat.register('file_reader', min_version='3.0')
def modern_file_reader(path: str) -> str:
with open(path, 'r', encoding=self.config.get('encoding', 'utf-8')) as f:
return f.read()
@self.compat.register('file_reader', max_version='2.7')
def legacy_file_reader(path: str) -> str:
with open(path, 'r') as f:
return f.read()
def read_file(self, path: str) -> str:
"""读取文件(自动版本兼容)"""
reader = self.compat.get_implementation('file_reader')
if reader:
return reader(path)
raise NotImplementedError("没有可用的文件读取实现")
def detect_environment(self) -> Dict[str, Any]:
"""检测运行环境"""
return {
'python_version': f"{sys.version_info.major}.{sys.version_info.minor}",
'platform': sys.platform,
'supports_fstrings': sys.version_info >= (3, 6),
'supports_type_hints': sys.version_info >= (3, 5),
'config': self.config
}
# 使用示例
def main():
project = CompatibleProject()
env_info = project.detect_environment()
print("环境信息:", json.dumps(env_info, indent=2))
try:
content = project.read_file("test.txt")
print("文件内容:", content[:100] if content else "空文件")
except Exception as e:
print(f"读取失败: {e}")
if __name__ == "__main__":
main()
这个封装案例提供了:
- 基础兼容工具:版本检查、装饰器
- 具体实现兼容:StringIO、ConfigParser等
- 高级封装:规则系统、动态分发
- 完整集成:配置文件、环境检测
使用时根据需要选择合适的兼容级别,确保代码在不同Python版本间平滑运行。