f-strings 多行打印顺序错误

f-strings multi-line printing wrong order

我想使用以下 python (3.8) 代码打印一份报告,但您可以看到 pandas 信息打印在顶部而不是底部。对于这种奇怪的行为,我似乎找不到任何解决方案。关于如何解决此问题的任何想法?

time = 600
file = 'election_file.csv'
report = (
    f'Data Diagnostic Report\n'
    f'Date & time: {time}\n'
    f'Data file: {file}\n'
    f'Data frame header (first five lines):\n {election.head()}\n\n'
    f'Data frame information:\n {election.info()}\n'
    f'end of report\n'
)
print(report)

输出:

time = 600...
<class 'pandas.core.frame.DataFrame'>
Index: 10 entries, Adams to Butler
Data columns (total 8 columns):
 #   Column   Non-Null Count  Dtype  
---  ------   --------------  -----  
 0   Obama    10 non-null     float64
 1   Romney   10 non-null     float64
 2   margin   10 non-null     float64
 3   state    10 non-null     object 
 4   total    10 non-null     int64  
 5   turnout  10 non-null     float64
 6   voters   10 non-null     int64  
 7   winner   9 non-null      object 
dtypes: float64(4), int64(2), object(2)
memory usage: 720.0+ bytes
Data Diagnostic Report
Date & time: 600
Data file: election_file.csv
Data frame header (first five lines):
                Obama     Romney     margin state   total    turnout  voters  \
Adams      35.482334  63.112001  27.629667    PA   41973  68.632677   61156   
Allegheny  56.640219  42.185820  14.454399    PA  614671  66.497575  924351   
Armstrong  30.696985  67.901278  37.204293    PA   28322  67.198140   42147   
Beaver     46.032619  52.637630   6.605012    PA   80015  69.483401  115157   
Bedford    22.057452  76.986570  54.929118    PA   21444  66.619031   32189   

           winner  
Adams      Romney  
Allegheny   Obama  
Armstrong  Romney  
Beaver     Romney  
Bedford    Romney  

Data frame information:
 None
end of report

那是因为 dataframe.info() 在调用时打印。因此,首先您会看到调用 dataframe.info() 的结果(在本例中为输出),然后才会打印 f-string。

换句话说,解释器首先评估f-string中使用的所有“变量”,然后才打印格式化字符串本身。这也是你看到

的原因
Data frame information:
  None

在输出中。 info() 打印数据然后 returns None(很像 built-in print)。

这种行为很容易重现:

def foo():
    print('foo')

print(f'Generated string {foo()}')

这输出

foo
Generated string None

解决此问题的方法是将报告一分为二:

time = 600
file = 'election_file.csv'
report = (
    f'Data Diagnostic Report\n'
    f'Date & time: {time}\n'
    f'Data file: {file}\n'
    f'Data frame header (first five lines):\n {election.head()}\n\n'
    f'Data frame information:\n '
)
print(report)
election.info()

report = (
    f'\n'
    f'end of report\n'
)
print(report)

这是因为 df.info() 打印了它被调用的那一刻,而 returns none. 试试这个,应该解决:

import io
buf = io.StringIO()
election.info(buf=buf)
electioninfo = buf.getvalue()

report = (
    f'Data Diagnostic Report\n'
    f'Date & time: {time}\n'
    f'Data file: {file}\n'
    f'Data frame header (first five lines):\n {election.head()}\n\n'
    f'Data frame information {electioninfo}:\n '
)
print(report)