The code is as below:
self.class_logg('http://example.com/api/?\
option=ajax&nologin=1&a=vmware_migrate_2&\
original_server_ip=%s&target_server_ip=%s&\
vmware_name=%s' % (self.ip, dest_node.ip, machine.name))
Because this string is so long, i have to split it into those several lines, but unfortunately find that in the log it prints like this:
http://example.com/api/?option=ajax &nologin=1&a=vmware_migrate_2 &original_server_ip=192.168.0.224$
Apparently it prints the indentation spaces there. How to resolve this problem?
the self.class_logg is just there for example, in my case the problem happens even if it is print.
You can just remove the \
self.class_logg(('http://example.com/api/?'
'option=ajax&nologin=1&a=vmware_migrate_2&'
'original_server_ip=%s&target_server_ip=%s&'
'vmware_name=%s' % (self.ip, dest_node.ip, machine.name)))
In Python, when strings are next to each other in the code, it will combine them. It is called "string grouping"
However, it seems to me that you would do better with a dictionary:
fields = {'option': 'ajax',
'nologin': '1',
'a': 'vmware_migrate_2',
'original_server_ip': self.ip,
'target_server_ip': dest_node.ip,
'vmware_name': machine.name}
params = '&'.join(['{}={}'.format(k, v) for k, v in fields.items()])
self.class_logg('http://example.com/api/?{}'.format(params))
If the order is important (which it should not be) You can use an OrderedDict, or a list of tuples.
You can make use of a handy trick that arises from how Python handles adjacent string constants:
self.class_logg('http://example.com/api/?'
'option=ajax&nologin=1&a=vmware_migrate_2&'
'original_server_ip=%s&target_server_ip=%s&'
'vmware_name=%s' % (self.ip, dest_node.ip, machine.name))
When Python sees two string constants immediately adjacent, it automatically joins them together to make a single string constant. This includes across lines, as long as Python recognizes that the next line is a continuation of the previous (which it will in this case, since you're inside a pair of parentheses).
You can see this in action with a simple example:
>>> print ('abc'
'def'
'ghi')
abcdefghi
You should use grouping instead of concatanation or any other line braking:
self.class_logg('http://example.com/api/?'
'option=ajax&nologin=1&a=vmware_migrate_2&'
'original_server_ip=%s&target_server_ip=%s&'
'vmware_name=%s' % (self.ip, dest_node.ip, machine.name))
Personal recommendation: you should use format instead of %:
self.class_logg(('http://example.com/api/?'
'option=ajax&nologin=1&a=vmware_migrate_2&'
'original_server_ip={}&target_server_ip={}&'
'vmware_name={}').format(self.ip, dest_node.ip, machine.name))
What you have here is one huge string with tabulations. Split in four different strings like so:
self.class_logg('http://example.com/api/?'\
'option=ajax&nologin=1&a=vmware_migrate_2&'\
'original_server_ip=%s&target_server_ip=%s&'\
'vmware_name=%s' % (self.ip, dest_node.ip, machine.name))
What matters are the single quotes in the start of every single string.
Related
I'm trying to join a list in python that contains several strings, some of which have \t and \n characters in them to create a string.
Say my list looks like this:
ll = ['list', 'of', '\tstrings', '\n\twith', 'newline', '\tcharacters']
ss = ':::'.join(ll)
print ss
prints ss with their \n and \t characters formatted:
list:::of::: strings:::
with:::newline::: characters\
While what I want it to print is:
'list:::of:::\tstrings:::\n\twith:::newline:::\tcharacters'
I've tried:
ss =[]
for l in ll:
ss.append(repr(l))
ss = ':::'.join(ll)
which does the same thing as above
and:
ss = ''
for l in ll:
ss += (repr(l)) + ':::'
print ss.strip(':::')
which is close but prints:
'list':::'of':::'\tstrings':::'\n\twith':::'newline':::'\tcharacters'
Tried a few more hacks but none seem to get me what I need.
The reason I need it like above is because I am writing CL arguments to a script that I call later on another machine. Passing a list as a CL argument doesn't work, so I was going to pass the list as a string (joined by ':::') and then on the other slide, split back into a list using ':::'. This works when just using join and split on the original list, however throws an error when I call the python script using the hardcoded CL arguments, because there's are newlines in list turned string argument. The last example works when passed through to the second machine, however gives me this list when I split it back:
["'list'", "'of'", "'\\tstrings'", "'\\n\\twith'", "'newline'", "'\\tcharacters'"]
when instead I need:
['list', 'of', '\tstrings', '\n\twith', 'newline', '\tcharacters']
UPDATE: I tried all of the suggestions below and more and still couldn't figure it out, so for now I'm just dumping the list into a text file on the first server, passing the file name instead of the list, then reading the text file to a list on the second server. Hopefully this workaround will work but i'm still looking for suggestions for a better way.
The joined string is already as you want it. You can confirm this by printing its representation:
ll = ['list', 'of', '\tstrings', '\n\twith', 'newline', '\tcharacters']
ss = ':::'.join(ll)
print repr(ss)
# 'list:::of:::\tstrings:::\n\twith:::newline:::\tcharacters'
Given the ss in your first code:
print ss.encode("string_escape")
(or possibly "unicode_escape" if there's any possibly of non-ASCII characters)
If you don't actually want the tabs and newlines for anything other than passing as arguments to some other system, you should probably use raw strings (r"\n\twith") to keep all the codes from ever being interpreted as escape codes.
No need to do data conversions that serve no purpose that you're just going to undo.
I'm teaching myself Python and can't see a huge difference between these two examples except the extra formatting options (eg. %r) that string formatting provides.
name = "Bob"
print "Hi, my name is %s." % name
print "Hi, my name is", name
Is there any reason in general why you'd prefer one over the other?
I realise that .format() is the preferred way to do this now, but this just for me to better understand how Python operates.
The primary difference between the two (which no one else seems to be describing) is this:
print "Hi, my name is %s." % name
Here, a new string is being constructed from the two strings (the string literal and the value of name). Interpolation (the % operator) is an operation you could use anywhere—for example, in a variable assignment or a function call—not just in a print statement. This newly-minted string is then printed (then discarded, because it is not given a name).
print "Hi, my name is", name
Here, the two strings are simply printed one after the other with a space in between. The print statement is doing all the work. No string operations are performed and no new string is created.
It is programming choice:
1) Using % clarifies the type to the reader of the code, but for each additional variable used, the programmer will need to spend time in modifying in 2 places
2) Using , implicitly does % so the reader will have to look back to know about he type. But it is quick and if code is intuitively written removes a lot of burdon of maintenance
So yes, it is choice of maintaining balance between, maintenance, readability and convenience.
The difference is that the comma is part of the print statement, not of the string. Attempting to use it elsewhere, e.g. binding a string to a name, will not do what you want.
I have a list of tuples in 'tups' and have applied the following code to filter. The list of tuples have the format [(floata,stra1,stra2),(floatb,strb1,strb2),...etc]
keys=sorted({t[2] for t in tups})
for key in keys:
group=filter(lambda t: t[2]==key,tups)
print '{}:\n\tmax: {}\n\tmin: {}'.format(key,max(group),min(group))
Initially I thought the curly brackets was a mistake and changed them to square brackets. I did not get a syntax error but the code did not work. As a last resort I changed the brackets back and everything was fine. Can someone explain the construction. Is this a dictionary comprehension? Where is this explained in the documentation?
If you mean the curly brackets in the first line, this is a set comprehension. This will create a set of the third item from every tuple in tups. A set is similar to a list, but without order, and therefore cannot contain duplicates.
If you mean the brackets in the string, this is just new-style string formatting. Calling str.format() changes those braces into the passed values.
Before Python 2.6, you would have used:
print '%s:\n\tmax: %s\n\tmin: %s' % (key,max(group),min(group))
to format a string using placeholders (the %s).
Since Python 2.6, you can use the {} syntax for the placeholder and .format instead:
print '{}:\n\tmax: {}\n\tmin: {}'.format(key,max(group),min(group))
or using positional arguments:
print '{0}:\n\tmax: {2}\n\tmin: {1}'.format(key,min(group),max(group))
(notice that I changed the order of the arguments, but the output is the same: we used {2} to represent the third argument...)
Just an advice: when you get a lot of arguments, it's easier to name them, as:
print '{key}:\n\tmax: {groupmax}\n\tmin: {groupmin}'.format(key=key,groupmin=min(group),groupmax=max(group))
The .format syntax is more powerful than the % one: examples are available in the documentation.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How can I print a literal “{}” characters in python string and also use .format on it?
Basically, I want to use .format(), like this:
my_string = '{{0}:{1}}'.format('hello', 'bonjour')
And have it match:
my_string = '{hello:bonjour}' #this is a string with literal curly brackets
However, the first piece of code gives me an error.
The curly brackets are important, because I'm using Python to communicate with a piece of software via text-based commands. I have no control over what kind of formatting the fosoftware expects, so it's crucial that I sort out all the formatting on my end. It uses curly brackets around strings to ensure that spaces in the strings are interpreted as single strings, rather than multiple arguments — much like you normally do with quotation marks in file paths, for example.
I'm currently using the older method:
my_string = '{%s:%s}' % ('hello', 'bonjour')
Which certainly works, but .format() seems easier to read, and when I'm sending commands with five or more variables all in one string, then readability becomes a significant issue.
Thanks!
Here is the new style:
>>> '{{{0}:{1}}}'.format('hello', 'bonjour')
'{hello:bonjour}'
But I thinking escaping is somewhat hard to read, so I prefer to switch back to the older style to avoid escaping:
>>> '{%s:%s}' % ('hello', 'bonjour')
'{hello:bonjour}'
I am evaluating hundreds of thousands of html files. I am looking for particular parts of the files. There can be small variations in the way the files were created
For example, in one file I can have a section heading (after I converted it to upper and split then joined the text to get rid of possibly inconsistent white space:
u'KEY1A\x97RISKFACTORS'
In another file I could have:
'KEY1ARISKFACTORS'
I am trying to create a dictionary of possible responses and I want to compare these two and conclude that they are equal. But every substitution I try to run the first string to remove the '\97 does not seem to work
There are a fair number of variations of keys with various representations of entities so I would really like to create a dictionary more or less automatically so I have something like:
key_dict={'u'KEY1A\x97RISKFACTORS':''KEY1ARISKFACTORS',''KEY1ARISKFACTORS':'KEY1ARISKFACTORS',. . .}
I am assuming that since when I run
S1='A'
S2=u'A'
S1==S2
I get
True
I should be able to compare these once the html entities are handled
What I specifically tried to do is
new_string=u'KEY1A\x97RISKFACTORS'.replace('|','')
I got an error
Sorry, I have been at this since last night. SLott pointed out something and I see I used the wrong label I hope this makes more sense
You are correct that if S1='A' and S2 = u'A', then S1 == S2. Instead of assuming this though, you can do a simple test:
key_dict= {u'A':'Value1',
'A':'Value2'}
print key_dict
print u'A' == 'A'
This outputs:
{u'A': 'Value2'}
True
That resolved, let's look at:
new_string=u'KEY1A\x97DEMOGRAPHICRESPONSES'.replace('|','')
There's a problem here, \x97 is the value you're trying to replace in the target string. However, your search string is '|', which is hex value 0x7C (ascii and unicode) and clearly not the value you need to replace. Even if the target and search string were both ascii or unicode, you'd still not find the '\x97'. Second problem is that you are trying to search for a non-unicode string in a unicode string. The easiest solution, and one that makes the most sense is to simply search for u'\x97':
print u'KEY1A\x97DEMOGRAPHICRESPONSES'
print u'KEY1A\x97DEMOGRAPHICRESPONSES'.replace(u'\x97', u'')
Outputs:
KEY1A\x97DEMOGRAPHICRESPONSES
KEY1ADEMOGRAPHICRESPONSES
Why not the obvious .replace(u'\x97','')? Where does the idea of that '|' come from?
>>> s = u'KEY1A\x97DEMOGRAPHICRESPONSES'
>>> s.replace(u'\x97', '')
u'KEY1ADEMOGRAPHICRESPONSES'