1

How can I avoid lines like:

this_long_variable_name = this_long_variable_name.replace('a', 'b')

I thought I could avoid it by making a function, repl,

def repl(myfind, myreplace, s): 
        s = s.replace(myfind, myreplace)
        print(s) # for testing purposes
        return s

but because of stuff about the local vs. global namespaces that I don't understand, I can't get the function to return a changed value for this_long_variable_name. Here's what I've tried:

this_long_variable_name = 'abbbc'
repl('b', 'x', this_long_variable_name)
print('after call to repl, this_long_variable_name =', this_long_variable_name)

The internal print statement shows the expected: axxxc The print statement after the call to repl show the unchanged: abbbbc

Of course, it works if I give up and accept the redundant typing:

this_long_variable_name = repl('b', 'x', this_long_variable_name)

BTW, it's not just about the length of what has to be retyped, even if the variable's name were 'a,' I would not like retyping a = a.replace(...)

Since in the function s is a parameter, I can't do: global s

I even tried:

this_long_variable_name.repl('b', 'x')

which shows you both how little I understand and how desperate I am.

Harry Binswanger
  • 1,069
  • 10
  • 12
  • 1
    Strings are immutable, and parameters are *call by value* so you can not do that. – Willem Van Onsem Nov 11 '17 at 18:59
  • I mean, say that for some reason we could that. What would be the result of `repl('a','b', some_function_call('with','arguments'))`. In that case there is not a reference to the string (we have). – Willem Van Onsem Nov 11 '17 at 19:00
  • I'm afraid typing it out is your best option. While yes, there are things you can do to work around this problem, all they're going to do is to make your code smelly. Typing it out is 1) least confusing for people reading your code and 2) the only solution that doesn't involve doing something ugly. – Aran-Fey Nov 11 '17 at 19:00

2 Answers2

1

The issue you're running into is that Python strings are immutable. str.replace() returns an entirely new string, so in s = s.replace(myfind, myreplace), the name s no longer refers to the original string, which is why you don't see any change on the outside of the function's namespace.

There probably isn't a great solution to your problem. I recommend using a modern IDE or Python REPL with autocompletion to alleviate it. Trying to abuse the standard way of writing things like this may feel good to you, but it will confuse anyone else looking at your code.

Josh Karpel
  • 2,110
  • 2
  • 10
  • 21
0

Harry it does not work because inside your repl function you actually have a local copy of the content of your this_long_variable_name. This is called "pass by copy" which means python hands over a copy to the function. Unfortunately this is how python does it. Check also here:

Python: How do I pass a string by reference?

Also strings are immutable in python so if you wanna change them you always create a new modified version. Check here:

Aren't Python strings immutable?

Question would be why should you need long variable names in the first place?

Stefan Lindblad
  • 410
  • 2
  • 17
  • Python is not pass-by-copy - see [this talk](https://youtu.be/_AEJHKGk9ns) for an excellent overview. – Josh Karpel Nov 11 '17 at 19:04
  • Thanks, all. I respond to the desire to avoid "smelly" code. It's parsimony that motivates this in the first place. I understand that strings are immutable, and I almost understand pass by reference vs. pass by value. Almost. :) I use long filenames (rarely as long as my example) to make the code self-documenting. Okay, not self-documenting but a step in that direction. Thanks to all, and I accept defeat with bowed head. – Harry Binswanger Nov 11 '17 at 19:51