Reputation: 135
I am writing a python script that uses the string.replace()
method a lot. I know that if I was importing a python method from a module I could change its name using from
like so:
from time import sleep as x
And then, x(5)
would be the same as time.sleep(5)
. But how can I do that to the replace() function? It isn't from any external module, and I have tried to do this:
x = replace()
But it doesn't work. It says NameError: name 'replace' is not defined
.
So please tell me how to "rename" the built-in replace function.
Upvotes: 3
Views: 11602
Reputation: 977
This is absolutely NOT advisable to do in any of your projects. But this is possible: We could do some metahacking - replacing the builtin str with our custom one
class myStr(str):
def def my_replace(self, __old, __new, __count):
return self.replace(__old, __new, __count)
__builtins__.__dict__['str'] = myStr
Now the all usages of str are replaced with our implementation. You can add or change whatever you want. In our case both replace methods will work, one inherited from str and one created by us:
print('dsadas'.replace('d', '_'))
>>> _sa_as
print('dsadas'.my_replace('d', '_'))
>>> _sa_as
But remember this is fun, but using those technics in real project could ruin a lot of other functionality.
Upvotes: 0
Reputation: 281287
You can sort of do what you want:
a = 'asdf'
a_replace = a.replace
Now a_replace
is a bound method object that does a.replace(whatever)
when you call a_replace(whatever)
. You can also do
my_replace = str.replace
my_replace('asdf', 'a', 'f') # calls 'asdf'.replace('a', 'f')
However, what you probably want is
some_magic()
'asdf'.my_replace('a', 'f') # calls 'asdf'.replace('a', 'f')
and that's not possible without messing with things you're really not supposed to mess with:
# Awful hack. Last resort only.
import gc
for referrer in gc.get_referrers(str.replace):
if type(referrer) is dict and str.__dict__ in gc.get_referrers(referrer):
# Almost certainly the dict behind str's dictproxy.
referrer['my_replace'] = str.replace
break
Upvotes: 0
Reputation: 365835
First, you should almost never be using string.replace
. As the docs say:
The following list of functions are also defined as methods of string and Unicode objects; see section String Methods for more information on those. You should consider these functions as deprecated…
Second, this is wrong for two separate reasons:
x = replace()
First, there is no builtin named replace
, and there's no global in your module named replace
either. If you did from string import *
or from string import replace
, then you wouldn't get this error—but if you were doing that, you could just do from string import replace as x
, exactly as you're already doing for time.sleep
.
Second, those parentheses mean that you're calling the function, and assigning its return value to x
, not using the function itself as a value.
So, I think what you want is this:
x = str.replace
That's accessing the replace
method on str
objects, and storing it in x
. An "unbound method" like this can be called by passing an instance of str
(that is, any normal string) as the first argument. So:
x(my_string, ' ', '_')
If you want to add the name x
as a method on the str
class itself, what you want is called "monkeypatching", and normally, it's very simple:
str.x = str.replace
Unfortunately, it doesn't work with most of the built-in types, at least in CPython; you'll get an error like this:
TypeError: can't set attributes of built-in/extension type 'str'
You could of course create your own subclass of str
, and use that all over the place instead of str
… but that won't help with string literals, strings you get back from other functions, etc., unless you wrap them explicitly. And I'm not sure it's worth the effort. But if you want to:
class s(str):
x = str.replace
Now you can do this:
z = s(function_returning_a_string())
z = z.x(' ', '_')
But notice that at the end, z
is back to being a str
rather than an s
, so if you want to keep using x
, you have to do this:
z = s(z.x(' ', '_'))
… and at a certain point, even if you're saving a few keystrokes, you're not saving nearly enough for the cost in readabiity and idiomaticitalnessity.
Upvotes: 5