如何将自己的自定义属性添加到现有的内置Python类型中?像一根绳子?

时间:2010-03-15 02:07:36

标签: python string attributes polymorphism

我想做这样的事......

def helloWorld():
  print "Hello world!"
str.helloWorld = helloWorld
"foo".helloWorld()

哪会打印出“Hello world!”

编辑:请参阅Can I add custom methods/attributes to built-in Python types?

8 个答案:

答案 0 :(得分:19)

在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()

虽然看起来很有意思,但可能很有意思...... 不要在生产代码中使用它。只是对内置类型进行子类化或尝试找出是否存在其他类型,可能更加pythonic,解决您的问题。

答案 1 :(得分:8)

总之,你不能。 Python方法将继承String并从那里开始工作。

答案 2 :(得分:3)

Ruby方式:

"1".to_i
"1".to_roman 

Python方式:

int("1")
Roman("1") # or 
Roman.fromstring("1") 

其中Roman适用于固定的内置类型列表或使用__int__方法的任何内容。

CPython的实现限制是您无法设置内置/扩展类型的属性。它伴随着文化偏好,避免使用猴子修补,支持独立函数,自定义类作为属性所需对象(甚至在极少数情况下进行子类化)。

答案 3 :(得分:2)

为此,您可以继承str

然而,虽然技术上可行,但大部分时间你都是内置类型(例如str),你正在寻找一种“有一种”关系,而不是'是-a',因此组合应该使用,而不是继承(意味着你应该创建一个带有字符串作为实例属性的类,而不是子类字符串)。

答案 4 :(得分:1)

你没有。使用单独的词典将“附加”(逻辑上讲)信息“附加”到不可变的值,如字符串或数字(字符串或数字值作为键,信息作为字典中的相应值)。

答案 5 :(得分:1)

这是一个想法。它并不完美,因为它不适用于所有字符串,但它可能会有所帮助。

设置字符串或任何其他对象的属性:

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'

答案 6 :(得分:0)

Python不支持该功能。

答案 7 :(得分:0)

你不能,它不是Pythonic。猴子修补不是Python常用的功能,所以对于性能 - 我相信 - 是因为你无法在构建它的类或实例上做到这一点。

事实上,它在Python中有自己的名字:duck-punching。