pythonclr库使用详解
clr 是 pythonnet 包提供的模块,用于在 python 和 .net 之间进行互操作。
1. 安装和基础配置
安装
pip install pythonnet
基础导入
import clr import sys import os
2. 加载 .net 程序集
方法一:加载 gac 中的程序集
import clr
# 加载系统程序集
clr.addreference("system")
clr.addreference("system.core")
clr.addreference("system.data")
clr.addreference("system.windows.forms")
from system import *
from system.io import *
from system.diagnostics import *
方法二:加载特定版本程序集
import clr
# 加载特定版本
clr.addreference("system, version=4.0.0.0, culture=neutral, publickeytoken=b77a5c561934e089")
# 或者使用 loadfrom
clr.addreferencebyname("system, version=4.0.0.0, culture=neutral, publickeytoken=b77a5c561934e089")
方法三:加载本地 dll 文件
import clr
import os
# 添加 dll 搜索路径
clr.addreference("yourassembly") # 如果 dll 在 python 路径中
# 或者指定完整路径
clr.addreferencetofile(r"c:\path\to\yourassembly.dll")
# 或者使用 loadfrom
clr.addreferencetofileandpath(r"c:\path\to\yourassembly.dll")
# 添加整个目录到搜索路径
clr.addreference(".") # 当前目录
3. 基本类型转换
数值类型
import clr
from system import *
# python 到 .net
int_value = int32(42)
double_value = double(3.14)
bool_value = boolean(true)
# .net 到 python
python_int = int(int_value)
python_float = float(double_value)
python_bool = bool(bool_value)
print(f".net int32: {int_value}, python int: {python_int}")
print(f".net double: {double_value}, python float: {python_float}")
字符串处理
import clr
from system import *
# 字符串转换
net_string = string("hello from .net")
python_string = str(net_string)
# 字符串操作
net_string = string("hello world")
length = net_string.length # 属性访问
substring = net_string.substring(0, 5) # 方法调用
contains = net_string.contains("hello") # 布尔方法
print(f"length: {length}")
print(f"substring: {substring}")
print(f"contains 'hello': {contains}")
数组和集合
import clr
from system import *
# 创建 .net 数组
int_array = array.createinstance(int32, 5)
for i in range(5):
int_array[i] = i * 10
# 或者使用更简单的方法
from system import array
int_array2 = array[int]([1, 2, 3, 4, 5])
# 列表转换
from system.collections.generic import list
net_list = list[int]()
net_list.add(1)
net_list.add(2)
net_list.add(3)
# python 列表到 .net 列表
python_list = [10, 20, 30]
net_list_from_python = list[int](python_list)
print(f".net 数组: {[x for x in int_array]}")
print(f".net 列表: {[x for x in net_list]}")
4. 创建和使用 .net 对象
实例化对象
import clr
from system import *
from system.io import *
from system.text import *
# 创建各种对象
sb = stringbuilder()
sb.append("hello")
sb.append(" world")
result = sb.tostring()
# 使用 fileinfo
file_info = fileinfo("test.txt")
print(f"文件存在: {file_info.exists}")
print(f"文件扩展名: {file_info.extension}")
# 使用 datetime
now = datetime.now
tomorrow = now.adddays(1)
time_span = tomorrow - now
print(f"现在: {now}")
print(f"明天: {tomorrow}")
print(f"时间差: {time_span.totalhours} 小时")
调用静态方法和属性
import clr
from system import *
from system.math import *
from system.environment import *
# 静态方法
max_value = max(10, 20)
sqrt_value = sqrt(16.0)
pi_value = pi
# 静态属性
machine_name = machinename
os_version = osversion
current_directory = currentdirectory
print(f"math.max(10, 20) = {max_value}")
print(f"math.sqrt(16) = {sqrt_value}")
print(f"pi = {pi_value}")
print(f"机器名: {machine_name}")
print(f"操作系统: {os_version}")
print(f"当前目录: {current_directory}")
5. 事件处理
订阅 .net 事件
import clr
from system import *
from system.timers import *
class timerhandler:
def __init__(self):
self.count = 0
def ontimerelapsed(self, sender, e):
self.count += 1
print(f"定时器触发 {self.count} 次 - {datetime.now}")
# 创建定时器
timer = timer(1000) # 1秒间隔
handler = timerhandler()
# 订阅事件
timer.elapsed += handler.ontimerelapsed
timer.start()
print("定时器已启动,按 enter 停止...")
input()
timer.stop()
使用委托
import clr
from system import *
# 定义委托处理程序
def message_handler(message):
print(f"收到消息: {message}")
# 使用 action 委托
action_delegate = action[str](message_handler)
action_delegate.invoke("hello from delegate!")
# 使用 func 委托
def add_numbers(a, b):
return a + b
func_delegate = func[int, int, int](add_numbers)
result = func_delegate.invoke(5, 3)
print(f"5 + 3 = {result}")
6. 异常处理
捕获 .net 异常
import clr
from system import *
from system.io import *
def file_operations():
try:
# 尝试读取不存在的文件
file_content = file.readalltext("nonexistent_file.txt")
print(file_content)
except filenotfoundexception as e:
print(f"文件未找到异常: {e.message}")
except unauthorizedaccessexception as e:
print(f"访问被拒绝: {e.message}")
except exception as e: # 捕获所有 .net 异常
print(f"其他异常: {e.gettype().name}: {e.message}")
def division_operations():
try:
from system import dividebyzeroexception
result = 10 / 0
except dividebyzeroexception as e:
print(f"除零异常: {e.message}")
except exception as e:
print(f"python 异常: {e}")
if __name__ == "__main__":
file_operations()
division_operations()
7. 高级功能
反射和动态调用
import clr
from system import *
from system.reflection import *
class reflectiondemo:
def explore_assembly(self, assembly_name):
# 加载程序集
clr.addreference(assembly_name)
assembly = assembly.load(assembly_name)
print(f"程序集: {assembly.fullname}")
print("类型列表:")
for type_obj in assembly.gettypes():
if type_obj.ispublic:
print(f" {type_obj.fullname}")
# 显示方法
methods = type_obj.getmethods(bindingflags.public | bindingflags.instance | bindingflags.static)
for method in methods[:3]: # 只显示前3个方法
print(f" 方法: {method.name}")
# 使用示例
demo = reflectiondemo()
demo.explore_assembly("system")
泛型使用
import clr
from system import *
from system.collections.generic import *
def generic_collections():
# 创建泛型字典
dictionary = dictionary[str, int]()
dictionary["one"] = 1
dictionary["two"] = 2
dictionary["three"] = 3
# 遍历字典
for kvp in dictionary:
print(f"key: {kvp.key}, value: {kvp.value}")
# 泛型列表
list_of_strings = list[str]()
list_of_strings.add("apple")
list_of_strings.add("banana")
list_of_strings.add("cherry")
# 使用 linq (需要引用 system.linq)
try:
clr.addreference("system.core")
from system.linq import enumerable
filtered = enumerable.where(list_of_strings, lambda x: x.startswith("a"))
print("以 a 开头的项目:")
for item in filtered:
print(f" {item}")
except exception as e:
print(f"linq 不可用: {e}")
if __name__ == "__main__":
generic_collections()
多线程编程
import clr
from system import *
from system.threading import *
from system.componentmodel import *
class backgroundworkerdemo:
def __init__(self):
self.worker = backgroundworker()
self.worker.workerreportsprogress = true
self.worker.workersupportscancellation = true
self.worker.dowork += self.on_do_work
self.worker.progresschanged += self.on_progress_changed
self.worker.runworkercompleted += self.on_work_completed
def on_do_work(self, sender, e):
worker = sender
for i in range(1, 101):
if worker.cancellationpending:
e.cancel = true
return
thread.sleep(50) # 模拟工作
worker.reportprogress(i, f"处理项目 {i}")
def on_progress_changed(self, sender, e):
print(f"进度: {e.progresspercentage}% - {e.userstate}")
def on_work_completed(self, sender, e):
if e.cancelled:
print("操作被取消")
elif e.error:
print(f"发生错误: {e.error.message}")
else:
print("操作完成!")
def start(self):
self.worker.runworkerasync()
def cancel(self):
self.worker.cancelasync()
# 使用示例
demo = backgroundworkerdemo()
demo.start()
print("后台工作已启动,按 enter 取消...")
input()
demo.cancel()
8. 实际应用案例
案例1:文件监控
import clr
from system import *
from system.io import *
class filemonitor:
def __init__(self, path):
self.watcher = filesystemwatcher()
self.watcher.path = path
self.watcher.includesubdirectories = true
# 订阅事件
self.watcher.created += self.on_file_created
self.watcher.changed += self.on_file_changed
self.watcher.deleted += self.on_file_deleted
self.watcher.renamed += self.on_file_renamed
def on_file_created(self, sender, e):
print(f"文件创建: {e.fullpath}")
def on_file_changed(self, sender, e):
print(f"文件修改: {e.fullpath}")
def on_file_deleted(self, sender, e):
print(f"文件删除: {e.fullpath}")
def on_file_renamed(self, sender, e):
print(f"文件重命名: {e.oldfullpath} -> {e.fullpath}")
def start(self):
self.watcher.enableraisingevents = true
print(f"开始监控目录: {self.watcher.path}")
def stop(self):
self.watcher.enableraisingevents = false
print("停止监控")
# 使用示例
monitor = filemonitor(".")
monitor.start()
print("文件监控已启动,按 enter 停止...")
input()
monitor.stop()
案例2:windows 服务交互
import clr
from system import *
from system.serviceprocess import *
class servicemanager:
def list_services(self):
services = servicecontroller.getservices()
print("系统服务列表:")
for service in services:
status = service.status
print(f" {service.servicename} - {service.displayname} - {status}")
def control_service(self, service_name, action):
try:
service = servicecontroller(service_name)
if action == "start":
if service.status == servicecontrollerstatus.stopped:
service.start()
service.waitforstatus(servicecontrollerstatus.running, timespan.fromseconds(30))
print(f"服务 {service_name} 已启动")
else:
print(f"服务 {service_name} 不是停止状态")
elif action == "stop":
if service.status == servicecontrollerstatus.running:
service.stop()
service.waitforstatus(servicecontrollerstatus.stopped, timespan.fromseconds(30))
print(f"服务 {service_name} 已停止")
else:
print(f"服务 {service_name} 不是运行状态")
elif action == "restart":
if service.status == servicecontrollerstatus.running:
service.stop()
service.waitforstatus(servicecontrollerstatus.stopped, timespan.fromseconds(30))
service.start()
service.waitforstatus(servicecontrollerstatus.running, timespan.fromseconds(30))
print(f"服务 {service_name} 已重启")
else:
print(f"服务 {service_name} 不是运行状态")
except exception as e:
print(f"操作服务时出错: {e}")
# 使用示例
manager = servicemanager()
manager.list_services()
# 注意:需要管理员权限
# manager.control_service("themes", "stop")
9. 调试和故障排除
调试技巧
import clr
from system import *
import traceback
def debug_net_interop():
try:
# 查看已加载的程序集
print("已加载的程序集:")
for assembly in clr.listassemblies():
print(f" {assembly}")
# 检查类型信息
clr.addreference("system")
from system import string
string_type = type(string("test"))
print(f"string 类型: {string_type}")
print(f"string 方法: {[method for method in dir(string) if not method.startswith('_')][:5]}")
except exception as e:
print(f"调试过程中出错: {e}")
traceback.print_exc()
def memory_management():
"""内存管理示例"""
import gc
# 创建大量 .net 对象
objects = []
for i in range(1000):
sb = stringbuilder()
sb.append(f"string {i}")
objects.append(sb)
print(f"创建了 {len(objects)} 个对象")
# 强制垃圾回收
gc.collect()
print("垃圾回收完成")
if __name__ == "__main__":
debug_net_interop()
memory_management()
10. 性能优化建议
import clr
from system import *
import time
class performanceoptimizer:
@staticmethod
def benchmark_operations():
"""性能基准测试"""
from system.text import stringbuilder
# 测试字符串拼接性能
start_time = time.time()
# 方法1:使用 python 字符串拼接
result1 = ""
for i in range(10000):
result1 += str(i)
time1 = time.time() - start_time
# 方法2:使用 .net stringbuilder
start_time = time.time()
sb = stringbuilder()
for i in range(10000):
sb.append(str(i))
result2 = sb.tostring()
time2 = time.time() - start_time
print(f"python 字符串拼接: {time1:.4f} 秒")
print(f".net stringbuilder: {time2:.4f} 秒")
print(f"性能提升: {time1/time2:.2f}x")
@staticmethod
def batch_operations():
"""批量操作优化"""
from system.collections.generic import list
# 不推荐的写法:逐个添加
slow_list = list[int]()
start_time = time.time()
for i in range(10000):
slow_list.add(i)
slow_time = time.time() - start_time
# 推荐的写法:批量添加
fast_list = list[int]()
start_time = time.time()
fast_list.addrange(range(10000))
fast_time = time.time() - start_time
print(f"逐个添加: {slow_time:.4f} 秒")
print(f"批量添加: {fast_time:.4f} 秒")
print(f"性能提升: {slow_time/fast_time:.2f}x")
if __name__ == "__main__":
performanceoptimizer.benchmark_operations()
performanceoptimizer.batch_operations()
总结
clr 库提供了强大的 python 与 .net 互操作能力:
- 程序集加载:支持 gac、本地文件等多种方式
- 类型转换:自动处理基本类型转换
- 对象操作:创建实例、调用方法、访问属性
- 事件处理:订阅 .net 事件和委托
- 异常处理:捕获和处理 .net 异常
- 高级特性:反射、泛型、多线程支持
使用时的注意事项:
- 确保架构匹配(x86/x64)
- 处理内存管理
- 注意性能优化
- 适当处理异常
这个库使得在 python 中利用丰富的 .net 生态系统成为可能。
以上就是python使用clr库实现与.net互操作教程的详细内容,更多关于python clr与.net互操作的资料请关注代码网其它相关文章!
发表评论