我有一个Python类的工作,我没有它的声明写访问。 我怎么能把一个自定义的方法(如__str__
),以不修改类声明该类创建的对象?
编辑:谢谢所有的答案。 我想他们所有,但他们并没有解决我的问题。 这里是我希望能澄清这个问题小例子。 我使用痛饮包装一个C ++类,其目的是覆盖__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)
example.hpp
struct example
{
int x;
};
example generate_example(int x);
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;
}
example.i
%module example
%{
#include "example.hpp"
%}
%include "example.hpp"
的CMakeLists.txt
cmake_minimum_required(VERSION 2.6)
find_package(SWIG REQUIRED)
include(${SWIG_USE_FILE})
find_package(PythonLibs)
include_directories(${PYTHON_INCLUDE_PATH})
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
set_source_files_properties(example.i PROPERTIES CPLUSPLUS ON)
swig_add_module(example python example.i example)
swig_link_libraries(example ${PYTHON_LIBRARIES})
if(APPLE)
set(CMAKE_SHARED_MODULE_CREATE_CXX_FLAGS "${CMAKE_SHARED_MODULE_CREATE_CXX_FLAGS} -flat_namespace")
endif(APPLE)
要构建并运行test.py,所有文件复制在一个目录,并在该目录中运行
cmake .
make
python test.py
这将导致以下的输出:
<example.example; proxy of <Swig Object of type 'example *' at 0x10021cc40> >
2
正如你可以看到痛饮对象都有自己STR功能,而这正是我试图重写。
如果你创建一个包装类,这与其他任何类,无论是内置或无法正常工作。 这就是所谓的“遏制和代表团”,这是继承一个共同的选择:
class SuperDuperWrapper(object):
def __init__(self, origobj):
self.myobj = origobj
def __str__(self):
return "SUPER DUPER " + str(self.myobj)
def __getattr__(self,attr):
return getattr(self.myobj, attr)
该__getattr__
方法将委托你SuperDuperWrapper对象的所有属性未定义请求所包含MyObj中的对象。 事实上,鉴于Python的动态类型,你可以使用这个类来SuperDuper'ly包裹任何内容:
s = "hey ho!"
sds = SuperDuperWrapper(s)
print sds
i = 100
sdi = SuperDuperWrapper(i)
print sdi
打印:
SUPER DUPER hey ho!
SUPER DUPER 100
在你的情况,你会采取从你不能修改函数返回的对象,并在自己的SuperDuperWrapper把它包起来,但你仍然可以以其他方式访问它,就好像它是基本对象。
print sds.split()
['hey', 'ho!']
>>> class C(object):
... pass
...
>>> def spam(self):
... return 'spam'
...
>>> C.__str__ = spam
>>> print C()
spam
它不会对它们使用类工作__slots__
。
创建一个子类。 例:
>>> import datetime
>>> t = datetime.datetime.now()
>>> datetime.datetime.__str__ = lambda self: 'spam'
...
TypeError: cant set attributes of built-in/extension type 'datetime.datetime'
>>> t.__str__ = lambda self: 'spam'
...
AttributeError: 'datetime.datetime' object attribute '__str__' is read-only
>>> class mydate(datetime.datetime):
def __str__(self):
return 'spam'
>>> myt = mydate.now()
>>> print t
2009-09-05 13:11:34.600000
>>> print myt
spam
这是我的回答另一个问题 :
import types
class someclass(object):
val = "Value"
def some_method(self):
print self.val
def some_method_upper(self):
print self.val.upper()
obj = someclass()
obj.some_method()
obj.some_method = types.MethodType(some_method_upper, obj)
obj.some_method()
请注意,使用Alex的子类的想法,你可以帮助自己多一点使用“ from
...... import
...... as
”:
from datetime import datetime as datetime_original
class datetime(datetime_original):
def __str__(self):
return 'spam'
所以现在的类有标准的名称,但不同的行为。
>>> print datetime.now()
'spam'
当然,这可能是危险的......
文章来源: Dynamically attaching a method to an existing Python object generated with swig?