我可以向内置 Python 类型添加自定义方法/属性吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4698493/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can I add custom methods/attributes to built-in Python types?
提问by jedmao
For example—say I want to add a helloWorld()method to Python's dict type. Can I do this?
例如——假设我想helloWorld()向 Python 的 dict 类型添加一个方法。我可以这样做吗?
JavaScript has a prototype object that behaves this way. Maybe it's bad design and I should subclass the dict object, but then it only works on the subclasses and I want it to work on any and all future dictionaries.
JavaScript 有一个以这种方式运行的原型对象。也许这是糟糕的设计,我应该对 dict 对象进行子类化,但是它只适用于子类,我希望它适用于任何和所有未来的字典。
Here's how it would go down in JavaScript:
以下是它在 JavaScript 中的表现:
String.prototype.hello = function() {
alert("Hello, " + this + "!");
}
"Jed".hello() //alerts "Hello, Jed!"
Here's a useful link with more examples— http://www.javascriptkit.com/javatutors/proto3.shtml
这是一个包含更多示例的有用链接 - http://www.javascriptkit.com/javatutors/proto3.shtml
采纳答案by TryPyPy
You can't directly add the method to the original type. However, you can subclass the type then substitute it in the built-in/global namespace, which achieves most of the effect desired. Unfortunately, objects created by literal syntax will continue to be of the vanilla type and won't have your new methods/attributes.
您不能直接将方法添加到原始类型。但是,您可以对类型进行子类化,然后在内置/全局命名空间中替换它,这样可以实现大部分所需的效果。不幸的是,由文字语法创建的对象将继续属于普通类型,并且不会有您的新方法/属性。
Here's what it looks like
这是它的样子
# 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'
"""
回答by Rafe Kettler
Yes, by subclassing those types. See unifying types and classes in Python.
是的,通过子类化这些类型。请参阅在 Python 中统一类型和类。
No, this doesn't mean that actual dicts will have this type, because that would be confusing. Subclassing a builtin type is the preferred way to add functionality.
不,这并不意味着实际的 dicts 会有这种类型,因为那会令人困惑。对内置类型进行子类化是添加功能的首选方式。
回答by totochto
Subclassing is the way to go in Python. Polyglot programmers learn to use the right tool for the right situation - within reason. Something as artfully constructed as Rails (a DSL using Ruby) is painfully difficult to implement in a language with more rigid syntax like Python. People often compare the two saying how similar they are. The comparison is somewhat unfair. Python shines in its own ways. totochto.
子类化是 Python 的方式。多语言程序员学会在正确的情况下使用正确的工具 - 在合理范围内。像 Rails(一种使用 Ruby 的 DSL)这样巧妙构建的东西很难用像 Python 这样语法更严格的语言来实现。人们经常比较这两者,说它们有多相似。这种比较有点不公平。Python 以自己的方式发光。托奇托。
回答by dameng
Just tried the forbbidenfruit!
刚试过禁果!
here is the code, very simple!
这是代码,非常简单!
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()
回答by Giovanni G. PY
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()
output
输出
t h i s i s t h e s t r i n g
Dataclass in Python 3.7
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()
output
输出
H e l l o
回答by fr_andres
NOTE: this QA is marked as duplicate to this one, but IMO it asks for something different. I cannot answer there, so I am answering here.
注意:这个QA被标记为复制到这一个,但IMO它要求不同的东西。我无法在那里回答,所以我在这里回答。
Specifically, I wanted to inherit from strand add custom attributes. Existing answers (especially the ones saying you can't) didn't quite solve it, but this worked for me:
具体来说,我想继承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
Hopefully this helps someone! Cheers,
Andres
希望这对某人有所帮助!干杯,
安德烈斯

