- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我是python新手,对python 2.7中的__func__
不太了解。
我知道当我这样定义一个类时:
class Foo:
def f(self, arg):
print arg
我可以使用 Foo().f('a')
或 Foo.f(Foo(), 'a')
来调用这个方法。但是,我不能通过 Foo.f(Foo, 'a')
调用此方法。但是我偶然发现我可以使用 Foo.f.__func__(Foo, 'a')
甚至 Foo.f.__func__(1, 'a')
来获取同样的结果。
我打印出Foo.f
、Foo().f
和Foo.f.__func__
的值,都是不同的。但是,我只有一段代码在定义中。谁能帮忙解释一下上面的代码是如何工作的,尤其是 __func__
?我现在真的很困惑。
最佳答案
当您访问 Foo.f
或 Foo().f
时,会返回一个 method;在第一种情况下它是未绑定(bind)的,在第二种情况下是绑定(bind)的。 python方法本质上是一个函数的包装器,该函数还包含对其作为方法的类的引用。绑定(bind)时,它还保存对实例的引用。
当您调用一个方法时,它会对传入的第一个参数进行类型检查,以确保它是一个实例(它必须是被引用类的实例,或者该类的子类)。当方法被绑定(bind)时,它会在你自己提供的未绑定(bind)方法上提供第一个参数。
正是这个方法对象具有 __func__
属性,它只是对包装函数的引用。通过访问底层函数而不是调用方法,您可以删除类型检查,并且您可以传入任何您想要的作为第一个参数。函数不关心参数类型,但方法关心。
请注意,在 Python 3 中,这已经改变; Foo.f
只是返回函数,而不是未绑定(bind)的方法。 Foo().f
返回一个仍然绑定(bind)的方法,但是没有办法再创建一个未绑定(bind)的方法了。
在底层,每个函数对象都有一个 __get__
method ,这是返回方法对象的内容:
>>> class Foo(object):
... def f(self): pass
...
>>> Foo.f
<unbound method Foo.f>
>>> Foo().f
<bound method Foo.f of <__main__.Foo object at 0x11046bc10>>
>>> Foo.__dict__['f']
<function f at 0x110450230>
>>> Foo.f.__func__
<function f at 0x110450230>
>>> Foo.f.__func__.__get__(Foo(), Foo)
<bound method Foo.f of <__main__.Foo object at 0x11046bc50>>
>>> Foo.f.__func__.__get__(None, Foo)
<unbound method Foo.f>
这不是最有效的代码路径,因此,Python 3.7 添加了一个新的 LOAD_METHOD
- CALL_METHOD
操作码对来替换当前的 LOAD_ATTRIBUTE
- CALL_FUNCTION
操作码对精确避免每次创建新的方法对象。此优化将 instance.foo()
的执行路径从 type(instance).__dict__['foo'].__get__(instance, type(instance))()
使用 type(instance).__dict__['foo'](instance)
,因此“手动”将实例直接传递给函数对象。这在现有微基准测试上节省了大约 20% 的时间。
关于python - 使用 __func__ 调用实例方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12935241/
名为 __func__ 的宏的存在是 C99 的一部分,其意图很明确,但它在给定函数中扩展为标准化的确切文本吗? 最佳答案 是的。宏被定义为扩展为函数的名称。 C11,§6.4.2.2 The ide
我正在尝试创建一个宏,该宏将根据调用宏的函数名称修改数据结构中的字段,请参见下文: #define REGISTER(func_name) data.func_name##_n++ struct da
#include char* __func__ = "hello"; void myfunc(void) { printf("%s\n", __func__); } int mai
我正在用 C++ 实现一个日志处理程序,它工作得很好,但是我发现有一件事是可用的,那就是记录器从中获取输出的地方。 我想这并不是什么大问题,但我偶然发现了 __func__ 标识符,它基本上会保留当前
我正在阅读 C/C++ 中的 __FUNCTION__/__func__(它们用于打印使用它们的函数的名称)。我读到的每个地方都说这些是宏,在预处理时被替换。因此,我使用命令 gcc -E prog.
#include void someFunc(void) { printf("%s\n"), __func__); } 每次调用该函数时都会打印: someFunc Java 的等价物是什么?
我在评论中看到使用 __func__ 存在安全风险。我需要了解这是怎么回事? 最佳答案 使用 __func__ 揭示二进制文件中的函数名称,从而减轻有权访问二进制文件的攻击者的工作。 关于c - __
如果我们在 C (C99/C11) 和 C++ 中的函数之外使用预定义变量 __func__ 会发生什么? #include const char* str = __func__; int main
我正在尝试通过将字符串存储在特殊部分 (__dlog) 来向 ELF 可执行文件添加元数据。当前的方法使用(滥用?)内联汇编来存储字符串并且几乎可以按预期工作。 #include #include
在实例方法的文档中指出: Methods also support accessing (but not setting) the arbitrary function attributes on t
大多数编译器都支持一些特殊的宏,例如 __FUNC__ 或 __PRETTY_FUNCTION__ 但我想知道如何在编译时验证它们是否可用,有这个来自 boost/current_function.h
谁能解释一下 Python datamodel reference 中关于用户定义函数 的以下部分是什么?是关于? When a user-defined method object is creat
在我正在处理的项目中给出以下代码: /* Pre-definitions in a pre-definitions file to be included in the project */ #ifd
我正在使用 gcc 编译 C99 代码。我想编写一个宏,它将返回一个包含函数名称和行号的字符串。 这是我的: #define INFO_MSG __FILE__ ":"__func__"()" 但是
我正在尝试构建一个调试日志消息函数,用于记录调用日志消息的文件、行和函数。 #define DEBUG_PANIC(p) CLogging::Debuglogf( "Debug marker (%s)
我是python新手,对python 2.7中的__func__不太了解。 我知道当我这样定义一个类时: class Foo: def f(self, arg): print
对于 gcc 项目,__FUNCTION__、__FILE__ 和 __func__ 返回的指针是否保证指向持久内存? (也就是说,我可以安全地引用另一个函数范围内的指针吗?)我知道 __func__
我想写一个 C 宏来接受这个: int foo() { MY_MACRO } 并将其扩展为: int foo() { _macro_var_foo++; } 我发现我不能使用 __func__
“C”标准是否支持类似于 __func__ 的函数参数名称? 最佳答案 不,C99 标准有以下内容: 6.10.8 Predefined macro names The following macro
我想定义一个宏来连接__func__(或__FUNCTION__)和__LINE__: 以下工作正常: // macro_test.cc #include #define STR2(X) #X #d
我是一名优秀的程序员,十分优秀!