For example—say I want to add a helloWorld()
method to Python's dict type. Can I do this?
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.
Here's how it would go down in 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
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'
"""
Yes, by subclassing those types. See unifying types and classes in 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.
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()
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
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
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.
来源:https://stackoverflow.com/questions/4698493/can-i-add-custom-methods-attributes-to-built-in-python-types