Yes, but you have to pass them in as arguments to format, and then refer to them wrapped in {} like you would the argument name itself:
print('\n{:^{display_width}}'.format('some text here', display_width=display_width))
Or shorter but a little less explicit:
print('\n{:^{}}'.format('some text here', display_width))
Since this question was originally posted, Python 3.6 has added f-strings, which allow you to do this without using the format method and it uses variables which are in scope rather than having to pass in the named variables as keyword arguments:
display_width = 50
text = 'some text here'
print(f'\n{text:^{display_width}}')
Answer from Brian Campbell on Stack OverflowVideos
Yes, but you have to pass them in as arguments to format, and then refer to them wrapped in {} like you would the argument name itself:
print('\n{:^{display_width}}'.format('some text here', display_width=display_width))
Or shorter but a little less explicit:
print('\n{:^{}}'.format('some text here', display_width))
Since this question was originally posted, Python 3.6 has added f-strings, which allow you to do this without using the format method and it uses variables which are in scope rather than having to pass in the named variables as keyword arguments:
display_width = 50
text = 'some text here'
print(f'\n{text:^{display_width}}')
Python f-string is more flexible.
>>> display_width = 50
>>> display_content = "some text here"
>>> print(f'\n{display_content:^{display_width}}')
some text here
You can use locals() function
s="svn cp {root_dir}/{trunk}/{root_dir}/{tag}/".format(**locals())
EDIT:
Since python 3.6 you can use string interpolation:
s = f"svn cp {root_dir}/{trunk}/{root_dir}/{tag}/"
Have you tried s="svn cp {root_dir}/{trunk}/ {root_dir}/{tag}/".format(**locals()) ?
Dynamically creating global variables can get hairy. It is much easier if you put it in a smaller scope ==> any object, e.g., a dictionary. You can achieve what you want like this
my_dictionary = dict()
for f in features:
my_dictionary['report_{}'.format(f)] = pd.DataFrame(index=data[f].unique(),columns=['Prediction','Actual'])
You can access the df like my_dictionary['report_Gender'] for example.
Another way would be to create a class:
class Reports:
pass
for f in features:
setattr(Reports, 'report_{}'.format(f), pd.DataFrame(index=data[f].unique(),columns=['Prediction','Actual'])
Then access as Reports.report_Gender etc...
You can use the setattr method if you really wan't to do it but I'll suggest to follow Ravi Patel's advice
for i in range(len(features)-1):
setattr(object_method_or_module_your_variable_belong,
name_for_you_varialbe,
pd.DataFrame(index=data[feature[i]].unique(),columns=['Prediction','Actual'])
See Python PEP 8: Function and Variable Names:
Function names should be lowercase, with words separated by underscores as necessary to improve readability.
Variable names follow the same convention as function names.
mixedCase is allowed only in contexts where that's already the prevailing style (e.g. threading.py), to retain backwards compatibility.
The Google Python Style Guide has the following convention:
module_name,package_name,ClassName,method_name,ExceptionName,function_name,GLOBAL_CONSTANT_NAME,global_var_name,instance_var_name,function_parameter_name,local_var_name.
A similar naming scheme should be applied to a CLASS_CONSTANT_NAME
You can parse the format yourself with the string.Formatter() class to list all references:
from string import Formatter
names = [fn for _, fn, _, _ in Formatter().parse(yourstring) if fn is not None]
Demo:
>>> from string import Formatter
>>> yourstring = "My name is {myname}"
>>> [fn for _, fn, _, _ in Formatter().parse(yourstring) if fn is not None]
['myname']
You could subclass Formatter to do something more fancy; the Formatter.get_field() method is called for each parsed field name, for example, so a subclass could work harder to find the right object to use.
Python 3.8 added an awesome solution for this using f-strings:
my_var = 123
print(f"{my_var = }")
Which will print
my_var = 123
You can use the str.format() method, which lets you interpolate other variables for things like the width:
'Number {i}: {num:{field_size}.2f}'.format(i=i, num=num, field_size=field_size)
Each {} is a placeholder, filling in named values from the keyword arguments (you can use numbered positional arguments too). The part after the optional : gives the format (the second argument to the format() function, basically), and you can use more {} placeholders there to fill in parameters.
Using numbered positions would look like this:
'Number {0}: {1:{2}.2f}'.format(i, num, field_size)
but you could also mix the two or pick different names:
'Number {0}: {1:{width}.2f}'.format(i, num, width=field_size)
If you omit the numbers and names, the fields are automatically numbered, so the following is equivalent to the preceding format:
'Number {}: {:{width}.2f}'.format(i, num, width=field_size)
Note that the whole string is a template, so things like the Number string and the colon are part of the template here.
You need to take into account that the field size includes the decimal point, however; you may need to adjust your size to add those 3 extra characters.
Demo:
>>> i = 3
>>> num = 25
>>> field_size = 7
>>> 'Number {i}: {num:{field_size}.2f}'.format(i=i, num=num, field_size=field_size)
'Number 3: 25.00'
Last but not least, of Python 3.6 and up, you can put the variables directly into the string literal by using a formatted string literal:
f'Number {i}: {num:{field_size}.2f}'
The advantage of using a regular string template and str.format() is that you can swap out the template, the advantage of f-strings is that makes for very readable and compact string formatting inline in the string value syntax itself.
I prefer this (new 3.6) style:
name = 'Eugene'
f'Hello, {name}!'
or a multi-line string:
f'''
Hello,
{name}!!!
{a_number_to_format:.1f}
'''
which is really handy.
I find the old style formatting sometimes hard to read. Even concatenation could be more readable. See an example:
'{} {} {} {} which one is which??? {} {} {}'.format('1', '2', '3', '4', '5', '6', '7')
Named replacement fields (the {...} parts in a format string) match against keyword arguments to the .format() method, and not positional arguments.
Keyword arguments are like keys in a dictionary; order doesn't matter, as they are matched against a name.
If you wanted to match against positional arguments, use numbers:
"{0} {1}".format(10, 20)
In Python 2.7 and up, you can omit the numbers; the {} replacement fields are then auto-numbered in order of appearance in the formatting string:
"{} {}".format(10, 20)
The formatting string can match against both positional and keyword arguments, and can use arguments multiple times:
"{1} {ham} {0} {foo} {1}".format(10, 20, foo='bar', ham='spam')
Quoting from the format string specification:
The field_name itself begins with an arg_name that is either a number or a keyword. If it’s a number, it refers to a positional argument, and if it’s a keyword, it refers to a named keyword argument.
Emphasis mine.
If you are creating a large formatting string, it is often much more readable and maintainable to use named replacement fields, so you don't have to keep counting out the arguments and figure out what argument goes where into the resulting string.
You can also use the **keywords calling syntax to apply an existing dictionary to a format, making it easy to turn a CSV file into formatted output:
import csv
fields = ('category', 'code', 'price', 'description', 'link', 'picture', 'plans')
table_row = '''\
<tr>
<td><img src="{picture}"></td>
<td><a href="{link}">{description}</a> ({price:.2f})</td>
</tr>
'''
with open(filename, 'rb') as infile:
reader = csv.DictReader(infile, fieldnames=fields, delimiter='\t')
for row in reader:
row['price'] = float(row['price']) # needed to make `.2f` formatting work
print table_row.format(**row)
Here, picture, link, description and price are all keys in the row dictionary, and it is much easier to see what happens when I apply the row to the formatting string.
Added benefits include
- You don't have to worry about the order of the arguments. They will fall in the right place in the strings as indicated by their names in the formatter.
- You can put the same argument in a string twice, without having to repeat the argument. E.g.
"{foo} {foo}".format(foo="bar")gives 'bar bar'
Note that you can give extra arguments without causing errors as well. All this is especially useful when
- you change the string formatter later on with less changes and thus smaller posibility for mistakes. If it does not contain new named arguments, the format function will still work without changing the arguments and put the arguments where you indicate them in the formatter.
- you can have multiple formatter strings sharing a set of arguments. In this case you could for instance have a dictionary with the all arguments and then pick them out in the formatter as you need them.
E.g.:
>d = {"foo":"bar", "test":"case", "dead":"beef"}
>print("I need foo ({foo}) and dead ({dead})".format(**d))
>print("I need test ({test}) and foo ({foo}) and then test again ({test})".format(**d))
I need foo (bar) and dead (beef)
I need test (case) and foo (bar) and then test again (case)