我希望在python中直接访问C语言的全局变量,直接通个python修改或者读取变量,而不通过方法,有什么办法可以实现吗?
听说可以通过__getattr__,__setattr__来实现,但是具体怎么使用,有相关的参考或者说明吗?非常感谢!
离线
首先第一步还是要用c模块做一个方法,比如有一个 _test.pyi 的 C 模块
# _test.pyi
def get(name: str) -> int:
pass
def set(name: str, val: int):
pass
然后下一步建立一个 test.py 的 py 模块,用 __getattr__ 和 __setattr__ 来进行数据绑定
# test.py
import _test
class DataBinding:
def __getattr__(self, name):
return _test.get(name)
def __setattr__(self, name, val):
_test.set(name, val)
然后就可以通过访问 DataBinding 类的属性来读写变量了
# main.py
import test
databinding = test.DataBinding()
databinding.A = 1 # 等效为 _test.set("A", 1)
val = databinding.A # 等效为 val = _test.get("A")
离线
https://docs.python.org/3/library/ctypes.html#accessing-values-exported-from-dlls
Accessing values exported from dlls
Some shared libraries not only export functions, they also export variables. An example in the Python library itself is the Py_OptimizeFlag, an integer set to 0, 1, or 2, depending on the -O or -OO flag given on startup.
ctypes can access values like this with the in_dll() class methods of the type. pythonapi is a predefined symbol giving access to the Python C api:
opt_flag = c_int.in_dll(pythonapi, "Py_OptimizeFlag")
print(opt_flag)
c_long(0)
离线
您可以使用 ctypes 类型的 .in_dll() 方法访问全局变量,该方法采用 ctypes DLL 引用和全局变量的名称
离线
@lyon1998
你这个操作只是操作变量,如果我要操作的是数组呢?要怎么操作,可以直接用list类型吗?
离线
@lyon1998
你这个操作只是操作变量,如果我要操作的是数组呢?要怎么操作,可以直接用list类型吗?
可以用一个对象的 __gitiem__ 和 __setitem__ 来做绑定
离线
li460135301 说:@lyon1998
你这个操作只是操作变量,如果我要操作的是数组呢?要怎么操作,可以直接用list类型吗?可以用一个对象的 __gitiem__ 和 __setitem__ 来做绑定
按照你说的,是这样操作吗?我好像操作了数组是无法绑定的!还是没有理解。谢谢!
···
# test.py
import _test
class DataBinding:
def __setattr__(self, name, val):
_test._set(name, val)
def __getitem__(self, name, key):
return _test._getitem(name, key)
def __setitem__(self, name, key, val):
print('name:', name)
print('key:', key)
print('val:', val)
_test._setitem(name, key, val)
def IN(self, addr: int) -> int:
return _test._in(addr)
···
···
# _test.pyi
def _get(self, name: str) -> int: ...
def _set(self, name: str, val: int): ...
def _getitem(self, name: str, key: int) -> int: ...
def _setitem(self, name: str, key: int, val: int): ...
···
离线
@li460135301
这里有一个参考示例:
import _test
class Test:
_name = ''
def __init__(self, name):
self._name = name
def __setitem__(self, key, val):
_test._setitem(self._name, key, val)
def __getitem__(self, key):
return _test._getitem(self._name, key)
A = Test('A')
A[0] = 1
print(A[0])
A[1] = 'B'
print(A[1])
离线
@lyon1998
好的,非常感谢,已经测试通过.
离线