当前位置: 首页 > news >正文

Python中的getattr/setattr和pybind11中的attr相關函數

Python中的getattr/setattr和pybind11中的attr相關函數

  • Python built-in functions
    • python - getattr
    • python - setattr
    • 測試
  • pybind11 - python_builtins
    • pybind11 - getattr
    • pybind11 - setattr
    • 測試
  • pybind11 - py::object_api::attr
    • 測試
  • 程式中用到的pybind11函數
    • py::scoped_interpreter
    • py::dict
    • py::exec
    • py::print
    • py::str

Python built-in functions

python - getattr

getattr屬於Python的built-in functions,參考其文檔python doc - getattr:

getattr(object, name)
getattr(object, name, default)
Return the value of the named attribute of object. name must be a string. If the string is the name of one of the object’s attributes, the result is the value of that attribute. For example, getattr(x, 'foobar') is equivalent to x.foobar. If the named attribute does not exist, default is returned if provided, otherwise AttributeError is raised. name need not be a Python identifier (see setattr()).Note Since private name mangling happens at compilation time, one must manually mangle a private attribute’s (attributes with two leading underscores) name in order to retrieve it with getattr().

回傳物件名稱為name的屬性的值。
參數 name 必須是一個字串,如果這個字串是物件的一個屬性名稱,那麼結果就是該屬性的值。例如:

getattr(x, 'foobar') 等同於 x.foobar

如果指定名稱的屬性不存在,則:

  • 若提供了 default 參數,則回傳 default
  • 否則會拋出 AttributeError。

注意:name 不一定要是合法的 Python 標幟符號(identifier)(參見 setattr())。

另外,由於私有名稱改寫(private name mangling)發生在編譯時期,若要使用 getattr() 取得私有屬性(即名稱有兩個前導底線的屬性),必須手動改寫mangle屬性的名稱(如連結中的第三個例子所示)。

python - setattr

setattr屬於Python的built-in functions,參考其文檔python doc - setattr:

setattr(object, name, value)
This is the counterpart of getattr(). The arguments are an object, a string, and an arbitrary value. The string may name an existing attribute or a new attribute. The function assigns the value to the attribute, provided the object allows it. For example, setattr(x, 'foobar', 123) is equivalent to x.foobar = 123.name need not be a Python identifier as defined in Identifiers and keywords unless the object chooses to enforce that, for example in a custom __getattribute__() or via __slots__. An attribute whose name is not an identifier will not be accessible using the dot notation, but is accessible through getattr() etc..Note Since private name mangling happens at compilation time, one must manually mangle a private attribute’s (attributes with two leading underscores) name in order to set it with setattr().

這是 getattr() 的對應函式。
參數為:一個物件、一個字串,以及一個任意值。

  • 這個字串可以是現有屬性的名稱,也可以是新的屬性名稱。
  • 只要物件允許,函式會將值指派給該屬性。
  • 例如:
setattr(x, 'foobar', 123)

等價於:

x.foobar = 123

  • name 不一定要是 Python 的識別字(identifier),除非物件選擇強制限制,例如透過自訂的 __getattribute__() 或使用 __slots__
  • 如果屬性名稱不是識別字,則無法用點號 (.) 來存取,但仍然可以透過 getattr() 等函式存取。

注意:

  • 私有名稱 (private name mangling) 是在 編譯時 發生的,
  • 如果要用 setattr() 設定私有屬性(名稱前有兩個底線 __),必須手動進行名稱 mangling。

測試

編寫test.py如下:

class Animal(object):legs = 4def run(self):print("I'm running!")if __name__ == "__main__":a = Animal();print("Initial leg value: ", getattr(a, "legs"))print("===================")setattr(a, "legs", 2)print("After set to 2:", getattr(a, "legs"))print("===================")print("run method:", getattr(a, "run"))print("call run method:")getattr(a, "run")()

運行結果如下:

Initial leg value:  4
===================
After set to 2: 2
===================
run method: <bound method Animal.run of <__main__.Animal object at 0x7f343aa38730>>
call run method:
I'm running!

pybind11 - python_builtins

group python_builtins
Unless stated otherwise, the following C++ functions behave the same as their Python counterparts.

除非另有說明,下列 C++ 函式的行為與其對應的 Python 函式相同。

pybind11 - getattr

pybind11 doc - getattr

inline object getattr(handle obj, handle name)
inline object getattr(handle obj, const char *name)
inline object getattr(handle obj, handle name, handle default_)
inline object getattr(handle obj, const char *name, handle default_)

pybind11 - setattr

pybind11 doc - getattr

inline void setattr(handle obj, handle name, handle value)
inline void setattr(handle obj, const char *name, handle value)

測試

編輯demo.cpp如下:

#include <pybind11/pybind11.h>
#include <pybind11/embed.h>  // py::scoped_interpreter
#include <string>namespace py = pybind11;int main() {// 啟動 Python 解譯器py::scoped_interpreter guard{};// 用 py::exec 定義 classpy::dict scope;py::exec(R"(
class Person:def __init__(self):self.name = "Alice"def greet(self):return "Hi, " + self.namep = Person()
)", scope);// 從 scope 取得 Python 物件py::object obj = scope["p"];// 使用 py::getattr / py::setattrpy::print("Via py::getattr:", py::getattr(obj, "name"));py::setattr(obj, "name", py::str("Charlie"));py::print("After py::setattr:", py::getattr(obj, "name"));py::print("Greeting:", py::getattr(obj, "greet")());return 0;
}

在這段程式當中用到了py::scoped_interpreter, py::dict , py::exec, py::print, py::str等函數,詳見程式中用到的pybind11函數。

嘗試過以下編譯指令但會出現linker error:

c++ -O3 -Wall -std=c++11 \demo.cpp -o demo \$(python3 -m pybind11 --includes) \$(python3-config --ldflags)

編譯:

c++ -O3 -Wall -std=c++11 demo.cpp -o demo \$(python3 -m pybind11 --includes) \-lpython3.8 -lpthread -ldl -lutil -lm

編譯成功後執行:

./demo

結果如下:

Via py::getattr: Alice
After py::setattr: Charlie
Greeting: Hi, Charlie

pybind11 - py::object_api::attr

pybind11 - py::object_api::attr

obj_attr_accessor attr(handle key) const
Return an internal functor to access the object’s attributes. Casting the returned detail::obj_attr_accessor instance to a handle or object subclass causes a corresponding call to getattr. Assigning a handle or object subclass causes a call to setattr.obj_attr_accessor attr(object &&key) const
See above (the only difference is that the key’s reference is stolen)str_attr_accessor attr(const char *key) const
See above (the only difference is that the key is provided as a string literal)

回傳一個 內部functor,用來存取物件的屬性。
將回傳的 detail::obj_attr_accessor 實例轉換(cast)成 handleobject 子類時,會觸發對應的 getattr 呼叫。
若將一個 handleobject 子類指定(assign)給它,則會觸發 setattr 呼叫。

測試

編輯demo.cpp如下:

#include <pybind11/pybind11.h>
#include <pybind11/embed.h>  // py::scoped_interpreter
#include <string>namespace py = pybind11;int main() {// 啟動 Python 解譯器py::scoped_interpreter guard{};// 用 py::exec 定義 classpy::dict scope;py::exec(R"(
class Person:def __init__(self):self.name = "Alice"def greet(self):return "Hi, " + self.namep = Person()
)", scope);// 從 scope 取得 Python 物件py::object obj = scope["p"];// 取得屬性py::print("Via .attr get:", obj.attr("name"));// 修改屬性obj.attr("name") = "Bob";py::print("After .attr() set:", obj.attr("name"));// 呼叫方法py::print("Greeting:", obj.attr("greet")());return 0;
}

使用相同的指令編譯執行後結果如下:

Via .attr get: Alice
After .attr() set: Bob
Greeting: Hi, Bob

程式中用到的pybind11函數

py::scoped_interpreter

pybind11 - Embedding the interpreter

The interpreter must be initialized before using any Python API, which includes all the functions and classes in pybind11. The RAII guard class scoped_interpreter takes care of the interpreter lifetime. After the guard is destroyed, the interpreter shuts down and clears its memory. No Python functions can be called after this.

在使用任何 Python API 之前,必須先初始化直譯器,它包含了 pybind11 中的所有函式與類別。
RAII guard class scoped_interpreter 會負責管理直譯器的生命週期。

  • 當這個守衛物件被銷毀時,直譯器就會關閉並清除記憶體。
  • 在這之後,就不能再呼叫任何 Python 函式。

py::dict

pybind11 Reference - py::dict

class dict : public object
Subclassed by Dict< K, V >, kwargs

py::exec

pybind11 Utilities - Evaluating Python expressions from strings and files

pybind11 provides the eval, exec and eval_file functions to evaluate Python expressions and statements. The following example illustrates how they can be used.C++11 raw string literals are also supported and quite handy for this purpose. The only requirement is that the first statement must be on a new line following the raw string delimiter R"(, ensuring all lines have common leading indent

pybind11 提供了 evalexeceval_file 這些函式,用來執行 Python 的運算式(expressions)與敘述(statements)。

C++11 的 raw string 字面值(raw string literals) 也被支援,並且在這種情境下非常方便。
唯一的要求是:第一個statememt必須從 raw string 分隔符 R"( 之後的 新的一行 開始,這樣可以確保所有程式碼行都有一致的縮排。

py::print

pybind11 Utilities - Using Python’s print function in C++

The usual way to write output in C++ is using std::cout while in Python one would use print. Since these methods use different buffers, mixing them can lead to output order issues. To resolve this, pybind11 modules can use the py::print() function which writes to Python’s sys.stdout for consistency.Python’s print function is replicated in the C++ API including optional keyword arguments sep, end, file, flush.

在 C++ 中,最常見的輸出方式是使用 std::cout,而在 Python 中則是使用 print
由於這兩種方法使用不同的緩衝區,如果混用,可能會導致輸出順序錯亂。

為了解決這個問題,pybind11 模組可以使用 py::print(),它會將輸出寫入 Python 的 sys.stdout,確保輸出的順序與一致性。

此外,Python 的 print 函式 也在 C++ API 中被複製(重現),並支援選用的關鍵字參數:

  • sep
  • end
  • file
  • flush

py::str

pybind11 Reference - py::str

class str : public object
Public Functionsinline explicit str(handle h)
Return a string representation of the object. This is analogous to the str() function in Python.

返回物件的字串表示形式。這相當於 Python 中的 str() 函式。


文章转载自:

http://oo3P9DvI.snktp.cn
http://vgMgD8zo.snktp.cn
http://2QLLn1sk.snktp.cn
http://3iq88Kri.snktp.cn
http://sTw4FQGB.snktp.cn
http://4BNYIwsu.snktp.cn
http://CxUVut36.snktp.cn
http://ldD5gTO7.snktp.cn
http://ghQGhBr5.snktp.cn
http://qbRE3vNk.snktp.cn
http://SFXCHRP6.snktp.cn
http://XwDgxST1.snktp.cn
http://RoCoiXsg.snktp.cn
http://qjPdUBNK.snktp.cn
http://KARvxjkI.snktp.cn
http://QnssvI9P.snktp.cn
http://4vyhR33S.snktp.cn
http://EBfJ02XF.snktp.cn
http://eDHr2Y9W.snktp.cn
http://syPs7NpC.snktp.cn
http://5ASxOUlq.snktp.cn
http://BNZ9oxAR.snktp.cn
http://5kXH3lkX.snktp.cn
http://vlzpVfdH.snktp.cn
http://nafkry8a.snktp.cn
http://OBYTSznZ.snktp.cn
http://wvKYtQl6.snktp.cn
http://iS38Bcmy.snktp.cn
http://o9TXBEY8.snktp.cn
http://PTU2iZuT.snktp.cn
http://www.dtcms.com/a/377651.html

相关文章:

  • Qt之Model/View架构
  • 龙虎榜——20250910
  • 嵌入式系统
  • Ngrok vs 飞网:内网穿透工具对比指南
  • 计算机毕设 java 高校家教平台 基于 SSM 框架的高校家教服务平台 Java+MySQL 的家教预约与课程管理系统
  • 招聘智能化浪潮:AI面试工具如何重塑招聘格局?
  • Java EE servlet与MySQL表单 工程实现增加查询数据
  • 上网管理行为-路由模式部署
  • Omni-UI:58同城鸿蒙ArkUI精心打造的UI组件库使用
  • 六自由度Stewart并联机器人simulink建模与模拟仿真
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘sympy’问题
  • 测试之道:从新手到专家实战(四)
  • 基于elementUI实现一个可编辑的表格(简洁版)
  • 智能美妆功能开发指南:直播美颜sdk的架构与算法解析
  • MySQL 浮点数、定点数与位类型:搞懂 3 类特殊数值的核心用法
  • 运动生理实验室解决方案 人体生理实验整体解决方案
  • Ping命令为何选择ICMP而非TCP/UDP?
  • 工业锅炉的“健康卫士”—状态监测与故障诊断
  • 大模型微调技术宝典:Transformer架构,从小白到专家
  • 同步框架与底层消费机制解决方案梳理
  • 计算机毕设 java 高校教材管理系统 基于 Java+SSM 的高校教材管控平台 Java+MySQL 的教材全流程管理系统
  • 用分层架构打造单体应用
  • TCP 拥塞控制设计空间课程要点总结
  • 工业网络融合:DEVICENET转PROFINET网关在汽车总装车间的应用
  • AI当调色总监用,合成图一秒融入,甲方看了都说绝
  • 深入浅出CRC校验:从数学原理到单周期硬件实现 (1) 初始CRC校验
  • 基于esp32c3 rust embassy 的墨水屏程序
  • 实战:用 Python 搭建 MCP 服务 —— 模型上下文协议(Model Context Protocol)应用指南
  • 亚马逊关键词引流:从手动操作到智能优化的全流程攻略
  • Windows 本地组策略重置标准操作程序 (SOP)