我想做类似这样的事情...
def helloWorld():
print "Hello world!"
str.helloWorld = helloWorld
"foo".helloWorld()
哪个代码将会打印出 "Hello world!"
编辑: 请参考Can I add custom methods/attributes to built-in Python types?
我想做类似这样的事情...
def helloWorld():
print "Hello world!"
str.helloWorld = helloWorld
"foo".helloWorld()
哪个代码将会打印出 "Hello world!"
编辑: 请参考Can I add custom methods/attributes to built-in Python types?
在CPython上,您可以使用ctypes来访问解释器的C-API,这样您就可以在运行时更改内置类型。
import ctypes as c
class PyObject_HEAD(c.Structure):
_fields_ = [
('HEAD', c.c_ubyte * (object.__basicsize__ -
c.sizeof(c.c_void_p))),
('ob_type', c.c_void_p)
]
_get_dict = c.pythonapi._PyObject_GetDictPtr
_get_dict.restype = c.POINTER(c.py_object)
_get_dict.argtypes = [c.py_object]
def get_dict(object):
return _get_dict(object).contents.value
def my_method(self):
print 'tada'
get_dict(str)['my_method'] = my_method
print ''.my_method()
尽管这看起来很有趣,而且也可能很有趣去解决...但不要在生产环境中使用它。只需对内置类型进行子类化或尝试找出另一种可能更符合Python风格的方法来解决问题。
type.__setattr__
的工作以维护内部不变量。例如,此链接的代码片段在第二个print
上打印错误结果,然后在第四个print
上崩溃。(forbiddenfruit
也有相同的缺陷。) - user2357112class PyObject_HEAD
是多余的。 - Joren简而言之,你不能这样做。Python的方式是子类化字符串并从那里开始工作。
这里有一个想法。虽然并不适用于所有字符串,但它可能会有所帮助。
要设置字符串或任何其他对象的属性:
def attr(e,n,v): #will work for any object you feed it, but only that object
class tmp(type(e)):
def attr(self,n,v):
setattr(self,n,v)
return self
return tmp(e).attr(n,v)
这里有一个例子:
>>> def helloWorld():
... print("hello world!") #python 3
...
>>> a=attr("foo",'heloWorld',helloWorld)
>>> a
'foo'
>>> a.helloWorld()
hello world!
>>> "foo".helloWorld()
Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
"foo".helloWorld()
AttributeError: 'str' object has no attribute 'helloWorld'
Ruby之道:
"1".to_i
"1".to_roman
Python 方式:
int("1")
Roman("1") # or
Roman.fromstring("1")
Roman
将在固定的内置类型列表或任何具有__int__
方法的内容上工作。
这是CPython的实现限制,您无法设置内置/扩展类型的属性。这伴随着文化偏好,即避免猴子补丁,而是使用独立函数、自定义类作为所需对象的属性(甚至在罕见情况下进行子类化)。
str
进行子类化。str
)时,您正在考虑一种“具有”关系,而不是“是一个”关系,因此应该使用组合而不是继承(这意味着您应该创建一个带有字符串作为实例属性的类,而不是子类化字符串)。Python不支持该功能。
你不能这样做,这不符合 Python 风格。在 Python 中,Monkey-patching 不是一个常用的功能,因此为了性能原因,我认为不能在其中内置的类或实例上进行 Monkey-patching。
事实上,在 Python 中它有自己的名字:duck-punching。
str
,而不是string
。 - Mike Graham