例如,假设我想向 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
不能直接将方法添加到原始类型中。但是,您可以对该类型进行子类化,然后在内置/全局命名空间中替换它,这可以实现大部分所需的效果。不幸的是,通过文字语法创建的对象将继续是普通类型,并且不会具有新的方法/属性。
这就是它的样子
# 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'
"""
刚刚尝试了禁果!
这是代码,很简单!
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()
确实是的,但是你必须定义一个相同类型的新类,并且它应该继承自该类型。
例如:
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))
注意:此 QA 被标记为与 this 重复,但在我看来,它要求不同的东西。我无法在那里回答,所以我在这里回答。
具体来说,我想继承
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
希望这对某人有帮助!干杯,安德烈斯
让我们考虑定义一个“列表”类并编写自己的函数,如下所示:
class list:
def custom_method (self):
return("Hey, I'm a custom method of list class")
#lets create an object here
obj = list([1,2,3])
print(obj.custom_method())
#The above runs fine, but a list has append() method also right?? let's try it
print(obj.append(1))
"""Now you will get Attribute error : list object has no attribute append()"""
因为,当您定义以“list”作为类名的类时,您将无法再访问“内置列表”类方法,因为“列表”被视为用户定义的类而不是内置类。
因此,为了摆脱这个错误,您可以继承“list”类的属性/成员,并且可以定义自己的方法或属性。因此,通过这种方式,您可以使用相同的类名调用用户定义/内置的类方法。
它看起来是这样的:
#Extending in-built list class
class list(list):
def custom_method (self):
return("Hey, I'm a custom method of list class")
obj = list([1,2,3])
print(obj.custom_method())
obj.append(1)
print(obj)
它运行良好,并将修改后的列表输出为 [1,2,3,1]。
注意:
但是当你这样做时,从长远来看可能会产生一些歧义问题,例如命名冲突例如,如果您有一个与用户定义的类中的内置函数具有相同签名的方法(此处为“列表”),那么它将在您不知情或不知情的情况下被覆盖,因此您可能无法使用其未来的原始功能。考虑到上面的代码,如果你定义了像
append(self, value)
这样的方法,append() 的原始功能将会丢失。
因此,最好使用不同的类名作为类名,而不是与内置类名相同例如,您可以如下声明一个类,这样不会引发任何错误,也不会遇到任何命名冲突。
class custom_list(list):
def custom_method (self):
return("Hey, I'm a custom method of list class")
obj = custom_list([1,2,3])
print(obj.custom_method())
obj.append(1)
print(obj)
编辑源代码。
如果您了解 C,则可以通过分叉 Python 存储库
并更改 Objects 文件夹 中所需的文件来更改函数方法。然后,阅读 README.rst
文件以获取构建说明。
import gc
dikt=gc.get_referents(list.__dict__)[0]
dikt['length']= property(lambda self: len(self)) # length attribute
def push(self,data):self+=[data]
dikt['push']= push # push method
a=[1,2,3]
print(a.length)
a.push(4)
print(a.length)
print(a)