我写了以下包装类.我想定义__setattr__它将所有属性重定向到包装类.但是,这阻止我初始化包装类.有什么优雅的方法可以解决这个
class Wrapper:
def __init__(self, value):
# How to use the default '__setattr__' inside '__init__'?
self.value = value
def __setattr__(self, name, value):
setattr(self.value, name, value)
Run Code Online (Sandbox Code Playgroud) 在python中,有许多函数可用作标准函数和上下文管理器.例如,open()可以称为:
my_file=open(filename,'w')
Run Code Online (Sandbox Code Playgroud)
要么
with open(filename,'w') as my_file:
Run Code Online (Sandbox Code Playgroud)
两者都给你一个my_file可以用来做任何你需要的对象.一般情况下,后者是优选的,但有时也可能想要做前者.
我已经能够弄清楚如何编写上下文管理器,或者通过创建一个带有__enter__和__exit__函数的类,或者通过@contextlib.contextmanager在函数上使用装饰器yield而不是return.然而,当我这样做时,我不能再直接使用该函数 - 使用装饰器,例如,我得到一个_GeneratorContextManager对象而不是想要的结果.当然,如果我把它作为一个类,我只会得到一个生成器类的实例,我假设它基本上是相同的.
那么我如何设计一个函数(或类)作为函数,返回一个对象或一个上下文管理器,返回一个_GeneratorContextManager或类似的东西?
编辑:
例如,假设我有一个类似下面的函数(这是高度简化的):
def my_func(arg_1,arg_2):
result=arg_1+arg_2
return my_class(result)
Run Code Online (Sandbox Code Playgroud)
所以函数需要一些参数,用它们做些什么,并使用那些东西的结果初始化一个类,然后返回它.最终结果是我有一个实例my_class,就像我有一个file对象,如果我已经调用open.如果我希望能够将此函数用作上下文管理器,我可以像这样修改它:
@contextlib.contextmanager
def my_func(arg_1,arg_2):
result=arg_1+arg_2 # This is roughly equivalent to the __enter__ function
yield my_class(result)
<do some other stuff here> # This is roughly equivalent to the __exit__function
Run Code Online (Sandbox Code Playgroud)
当作为上下文管理器调用时,它工作得很好,但我不再获得my_class调用为直接函数的实例.也许我只是做错了什么?
编辑2:
请注意,我确实可以完全控制my_class,包括向其添加功能的功能.从下面的接受的答案,我可以推断,我的困难来自于一个基本的误解朵朵:我在想,不管我叫(my_func …
我正在使用Python类,并且我没有对其声明的写入权限.如何__str__在不修改类声明的情况下将自定义方法(如)附加到从该类创建的对象中?
编辑:谢谢你的所有答案.我尝试了所有这些,但他们没有解决我的问题.这是一个最小的例子,我希望能澄清这个问题.我使用swig来包装C++类,目的是覆盖swig模块返回的对象的__str__功能.我使用cmake来构建示例:
test.py
import example
ex = example.generate_example(2)
def prnt(self):
return str(self.x)
#How can I replace the __str__ function of object ex with prnt?
print ex
print prnt(ex)
Run Code Online (Sandbox Code Playgroud)
example.hpp
struct example
{
int x;
};
example generate_example(int x);
Run Code Online (Sandbox Code Playgroud)
example.cpp
#include "example.hpp"
#include <iostream>
example generate_example(int x)
{
example ex;
ex.x = x;
return ex;
}
int main()
{
example ex = generate_example(2);
std::cout << ex.x << "\n";
return 1;
}
Run Code Online (Sandbox Code Playgroud)
example.i
%module example
%{ …Run Code Online (Sandbox Code Playgroud)