数字字典键在打印字符串时用作占位符?

问题描述

我有以下代码

https://git.website.com/test.git

运行时的输出为:

server {
    listen 80;
    listen [::]:80;

    listen 443 ssl;
    listen [::]:443 ssl;

    ssl_certificate /etc/ssl/ssl-bundle.crt;
    ssl_certificate_key /etc/ssl/private/ssl-private.key;

    root /srv/git;

    index index.html index.htm index.Nginx-debian.html;

    access_log /var/log/Nginx/git.access.log;
    error_log /var/log/Nginx/git.error.log;
    gzip off;

    location / {
        try_files $uri $uri/ =404;
    }

    # static repo files for cloning over https
    location ~ ^.*/objects/([0-9a-f]+/[0-9a-f]+|pack/pack-[0-9a-f]+.(pack|idx))$ {
        root /srv/git;
    }

    # requests that need to go to git-http-backend
    location ~ ^.*/(HEAD|info/refs|objects/info/.*|git-(upload|receive)-pack)$ {
        root /srv/git;

        fastcgi_pass  unix:/var/run/fcgiwrap.socket;
        fastcgi_param SCRIPT_FILENAME   /usr/lib/git-core/git-http-backend;
        fastcgi_param PATH_INFO         $uri;
        fastcgi_param GIT_PROJECT_ROOT  $document_root;
        fastcgi_param GIT_HTTP_EXPORT_ALL "";
        fastcgi_param REMOTE_USER $remote_user;
        include fastcgi_params;
    }   
}

我在任何地方都找不到解决方案。如果我要将git-http-backend中的键替换为字符串,例如board_dic = { 0: '_',1: '_',2: '_',3: '_',4: '_',5: '_',6: '_',7: '_',8: '_',} print("|{0}|{1}|{2}|\n|{3}|{4}|{5}|\n|{6}|{7}|{8}|".format(**board_dic) line 28,in <module> print("|{0}|{1}|{2}|\n|{3}|{4}|{5}|\n|{6}|{7}|{8}|".format(**board_dic)) IndexError: Replacement index 0 out of range for positional args tuple board_dic等,并将print语句中的占位符替换为{{1 }},'a''b'等,然后我的print语句将执行而没有任何问题。但是,似乎问题出在数字键字典值上。

为什么会这样,我该如何解决

解决方法

在使用格式字符串时,{1}之类的占位符代表“ format()”的第n个参数。这与命名的关键字参数不同。使用**board_dic会将它们分解为关键字参数。这就是它无法按预期工作的原因。

相反,您需要使用单个*来使用位置参数。但是随后您面临另一个问题:据我所知,字典排序仅是Python 3.7语言规范的一部分。在以前的版本中它已经很稳定,但是这是实现细节,在其他版本(pypy,jython等)中则无法保证。

因此,我们需要对其进行排序以确保100%可以正常工作。

由于键是数字,因此我们可以简单地对board_dic.items()进行排序。这将为我们提供稳定的替代产品。

然后,我们需要提取有效值。我们可以通过简单的列表理解来做到这一点。

更改之后,我们-只要字典中不包含任何遗漏的数字-100%可以确保输出正确。

我们可以使用.format()中的结果列表,只需使用一个“ positional-argument-expansion”。

board_dic = {
    0: '_',1: '_',2: '_',3: '_',4: '_',5: '_',6: '_',7: '_',8: '_',}

values = [value for _,value in sorted(board_dic.items())]

print("|{0}|{1}|{2}|\n|{3}|{4}|{5}|\n|{6}|{7}|{8}|".format(*values))
,

如果您知道要寻找的内容,请here进行说明:

field_name本身以arg_name开头,该arg_name可以是数字或关键字。 如果是数字,则表示位置参数;如果是关键字,则表示命名关键字参数。如果格式字符串中的数字arg_name依次为0、1、2,…,则可以全部省略(不只是某些数字),并且数字0、1、2,…将按该顺序自动插入。由于arg_name不是用引号分隔的,因此无法在格式字符串中指定任意字典键(例如,字符串'10'或':-]')。

简单来说,'{0} {1}'.format(...)的意思是“用{0}的第一个位置参数替换{1},并用format(...)的第二个位置参数替换format(1,2,c=3)

位置参数是在函数调用中未指定参数名称的情况下传递的位置参数。例如,在1中,2c=3是位置参数,而**board_dic是关键字参数。

但是format(**board_dic)语法指定关键字参数! format(0='_',1='_',2='_',...)等效于{0} 1 ,并且没有 个位置参数。因此,使用{1}{2}format等来获取第一个,第二个,第三个等位置自变量会失败。

为了将带有整数键的字典传递给print("|{d[0]}|{d[1]}|{d[2]}|\n|...".format(d=board_dic)) ,可以使用以下方法:

{{1}}

1 数字不允许作为关键字是另一个问题。

,

要使用其键将str.format方法的字典值转换为位置参数,可以将字典长度的range映射到字典的get方法,然后将输出序列解压缩为参数:

print("|{0}|{1}|{2}|\n|{3}|{4}|{5}|\n|{6}|{7}|{8}|".format(*map(board_dic.get,range(len(board_dic)))))