我可以为内置Python类型添加自定义方法/属性吗?

时间:2011-01-15 07:27:11

标签: python custom-attributes monkeypatching built-in-types

例如 - 假设我想在Python的dict类型中添加helloWorld()方法。我可以这样做吗?

JavaScript有一个行为方式的原型对象。也许这是糟糕的设计,我应该继承dict对象,但它只适用于子类,我希望它可以在任何和所有未来的字典上工作。

以下是JavaScript中的内容:

String.prototype.hello = function() {
    alert("Hello, " + this + "!");
}
"Jed".hello() //alerts "Hello, Jed!"

这是一个包含更多示例的有用链接 - http://www.javascriptkit.com/javatutors/proto3.shtml

7 个答案:

答案 0 :(得分:62)

您无法直接将方法添加到原始类型。但是,您可以对类型进行子类化,然后将其替换为内置/全局命名空间,从而实现所需的大部分效果。不幸的是,由文字语法创建的对象将继续属于vanilla类型,并且不会有新的方法/属性。

这就是它的样子

# Built-in namespace
import __builtin__

# Extended subclass
class mystr(str):
    def first_last(self):
        if self:
            return self[0] + self[-1]
        else:
            return ''

# Substitute the original str with the subclass on the built-in namespace    
__builtin__.str = mystr

print str(1234).first_last()
print str(0).first_last()
print str('').first_last()
print '0'.first_last()

output = """
14
00

Traceback (most recent call last):
  File "strp.py", line 16, in <module>
    print '0'.first_last()
AttributeError: 'str' object has no attribute 'first_last'
"""

答案 1 :(得分:1)

是的,通过继承这些类型。请参阅unifying types and classes in Python

不,这并不意味着实际的dicts会有这种类型,因为这会让人感到困惑。对内置类型进行子类化是添加功能的首选方法。

答案 2 :(得分:1)

就尝尝禁果吧!

代码很简单!

from forbiddenfruit import curse


def list_size(self):
    return len(self)

def string_hello(self):
    print("Hello, {}".format(self))

if __name__ == "__main__":
    curse(list, "size", list_size)
    a = [1, 2, 3]
    print(a.size())
    curse(str, "hello", string_hello)
    "Jesse".hello()

答案 3 :(得分:1)

是的,但是您必须定义一个相同类型的新类,并且它应该从该类型继承。

例如:

class list(list):
    def __init__(self,*args):
        super().__init__(args)
    def map(self,function):
        return [function(i) for i in self]

a = list(1,2,3,4,5)
Def double(i): return i*2

print(a.map(double))

答案 4 :(得分:0)

class MyString:
    def __init__(self, string):
        self.string = string
    def bigger_string(self):
        print(' '.join(self.string))

mystring = MyString("this is the string")
mystring.bigger_string()

输出

t h i s   i s   t h e   s t r i n g

Python 3.7中的数据类

from dataclasses import dataclass

@dataclass
class St:

    text : str

    def bigger(self) -> None:
        self.text = list(self.text)
        print(" ".join(self.text))

mys = St("Hello")
mys.bigger()

输出

H e l l o

答案 5 :(得分:0)

注意:此质量检查标记为与this one重复,但是IMO要求提供其他内容。我不能在那里回答,所以我在这里回答。


具体地说,我想从str继承并添加自定义属性。现有的答案(尤其是那些说您不能的答案)并不能完全解决问题,但这对我有用:

class TaggedString(str):
    """
    A ``str`` with a ``.tags`` set and ``.kwtags`` dict of tags.
    Usage example::
      ts = TaggedString("hello world!", "greeting", "cliche",
                        what_am_i="h4cker")
      (ts.upper(), ts.tags, ts.kwtags)
    """

    def __new__(cls, *args, **kwargs):
        return super().__new__(cls, args[0])

    def __init__(self, s, *tags, **kwtags):
        super().__init__()
        self.tags = set(tags)
        self.kwtags = kwtags

希望这对某人有帮助!干杯,
安德烈斯

答案 6 :(得分:-3)

子类化是Python的发展方向。 Polyglot程序员学会在正确的情况下使用正确的工具。像Rails这样巧妙构造的东西(使用Ruby的DSL)在使用像Python这样更严格的语法的语言中难以实现。人们常常比较两者说它们有多相似。这种比较有点不公平。 Python以自​​己的方式闪耀。 totochto。