简体   繁体   中英

Python String Concatenation - Unexpected Behavior

I am getting the absolute weirdest Python behavior possible and I cannot for the life of me figure it out. With any luck, someone out here has an idea of what's going on.

I am looping the following method:

def request_hiscores_for(name):
  print '+++++ request_hiscores_for() running +++++'+name
  print type(name)
  print '  Requesting hiscores for $name using request_hiscores_for()'.replace('$name',name)
  print '  Requesting hiscores for '+name+' using request_hiscores_for()'
  print '  Requesting hiscores for $name using request_hiscores_for()'.replace('$name','BLA')
  print '----- request_hiscores_for() ending ------\n'

and am getting output along the following lines:

+++++ request_hiscores_for() running +++++10032
<type 'str'>
 using request_hiscores_for()32
 using request_hiscores_for()32
  Requesting hiscores for BLA using request_hiscores_for()
----- request_hiscores_for() ending ------

+++++ request_hiscores_for() running +++++123 Lvs 2 Go
<type 'str'>
 using request_hiscores_for() Lvs 2 Go
 using request_hiscores_for() Lvs 2 Go
  Requesting hiscores for BLA using request_hiscores_for()
----- request_hiscores_for() ending ------

I'd like to point out how the string concatenation is quite literally making parts of the string disappear, and somehow concatenating the arguments in a different order. So... help would be appreciated.

Most probably your name variable's internal representation looks something like -

'10032\r'

Example to show that above representation (especially with the \\r at the end , without the \\n would cause the issue) -

In [17]: name = '10032\r'

In [19]: print('  Requesting hiscores for $name using request_hiscores_for()'.replace('$name',name))
 using request_hiscores_for()32

In [20]: name = '123 Lvs 2 Go\r'

In [21]: print('  Requesting hiscores for $name using request_hiscores_for()'.replace('$name',name))
 using request_hiscores_for() Lvs 2 Go

\\r is carriage return , it brings the cursor back to the start of the line , so any new characters that are print after that starting printing from the start of the line, therefore overwriting whatever was printed previously.

Most probably, wherever you are reading the names from, you are either directly getting the above string, or you are getting something like -

name = '10032\r\n'

But you are either splitting or stripping off \\n alone, example -

In [22]: name = '10032\r\n123 Lvs 2 Go\r\n'

In [23]: name.split('\n')
Out[23]: ['10032\r', '123 Lvs 2 Go\r', '']

If you are doing the spliting based on \\n , then do not do that, instead use - .splitlines() . Example -

In [24]: name.splitlines()
Out[24]: ['10032', '123 Lvs 2 Go']

If you are doing something like .strip('\\n') , then don't do that, use .strip() alone to remove all whitespaces or .strip('\\r\\n')


Also, it would be better to use string formatting, rather than your replace method. Something like -

print '  Requesting hiscores for {name} using request_hiscores_for()'.format(name=name)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM