How do I create new methods and attributes for built-in datatypes in python? [duplicate]
I want to create new methods for str
datatype. Here's what I tried
class str(str):
def __init__(self) -> None:
super().__init__()
def work(self):
# Just for testing
print("works")
Here, when I initialize strings using str()
this works but wrapping them around simple quotation this raises the error AttributeError: 'str' object has no attribute 'work'
Like this:
b = str("Hello world")
b.work()
Works as intended with stdout "works"
but,
a = "Hello world"
a.work()
Raises AttributeError: 'str' object has no attribute 'work'
I want to create new methods such that they work with these cases :
"foo".work()
str("foo").work() # <- This actually works :D
bar = "foo"; bar.work()
Thanks for the help.
Solution 1:
This can't be done, since str
is one of the immutable types in Python. Among the immutable types are bool
, int
, float
, tuple
, string
, frozenset
and perhaps a few more I don't know about.
With other types, you might be able to do something like this:
class MyClass:
def __str__(self):
return "my class"
def print_me_quoted(self):
print(f'"{self}"')
mc_old = MyClass()
MyClass.print_me_quoted = print_me_quoted
mc_new = MyClass()
# both now have it
mc_old.print_me_quoted()
mc_new.print_me_quoted()
It's still a spectacularly bad idea, to change the behaviour of a class by monkey-patching it like this, but it can be done. Expect your editor or IDE not to like it, or to understand it - you'll see warnings.
If you try this with str
:
def print_me_quoted(self):
print(f'"{self}"')
str.print_me_quoted = print_me_quoted
mc = str(10)
mc.print_me_quoted()
You get this TypeError
:
TypeError: cannot set 'print_me_quoted' attribute of immutable type 'str'
You could do it on your own version of str
:
class Str(str):
...
def print_me_quoted(self):
print(f'"{self}"')
Str.print_me_quoted = print_me_quoted
mc = Str(10)
mc.print_me_quoted()
But of course that does not change the standard behaviour of strings - which is exactly the point.