11

我更新了我的 python 解释器,但我认为旧的解释器仍然被调用。当我检查我得到的版本时:

$ python -V
Python 3.0.1

但我相信老口译员仍在被召唤。当我运行命令时:

python myProg.py

脚本运行正常。但是当我用命令调用它时

./myProg.py

我收到错误消息:

AttributeError: 'str' object has no attribute 'format'

这显然是由于调用了旧的解释器。我怎样才能解决这个问题?我运行 Mac OS X 10.5。是否与第一行有关:

#!/usr/bin/python

我刚开始使用 python,对解释语言不是很熟悉,所以我不太确定发生了什么。

4

6 回答 6

16

根据脚本的第一行#!/usr/bin/python,您正在调用 Python 解释器/usr/bin/python(很可能是 Mac OS X 附带的解释器)。您必须将该路径更改为安装 Python 3 解释器的路径(可能是/usr/local/bin/python/opt/local/bin/python);或者您可以将该行更改为 read #!/usr/bin/env python,这将调用变量中python列出的第一个PATH(这似乎是您安装的较新版本)。

于 2009-05-24T16:59:38.120 回答
6

首先,推荐的shebang线路是:

#!/usr/bin/env python

这将确保./foo.py当您调用 python 时调用的解释器与从命令行调用 python 时调用的解释器相同。

根据您的描述,我怀疑如果您这样做:

which python

它不会给你/usr/bin/python。它会给你一些别的东西,这就是 python 3 解释器所在的地方。您可以将您的 shebang 行修改为上述内容,或者将 python 解释器的路径替换为which.

于 2009-05-24T17:00:54.923 回答
3

试试which python。我会告诉你在你的环境中使用了哪个 python 解释器。如果它/usr/bin/python不像剧本中那样,那么你的怀疑就得到了证实。

于 2009-05-24T16:59:26.077 回答
3

您很可能怀疑 shebang 线路正在调用旧版本。您可能需要检查两件事:

1) /usr/bin/python 的解释器是什么版本:

/usr/bin/python -V

2)您安装的 python 3 解释器在哪里:

which python

如果您从命令行获得了正确的命令行,则将您的 shebang 行替换为:

#!/usr/bin/env python

附录:您也可以用指向 python 3 的符号链接替换旧版本的 python,但要注意任何主要的 OS X 更新(即:10.5.6 到 10.5.7)都可能会破坏这一点:

sudo mv /usr/bin/python /usr/bin/python25
sudo ln -s /path/to/python/3/python /usr/bin/python
于 2009-05-24T17:01:38.663 回答
2

运行 'which python' - 如果这给出的答案与 /usr/bin/python 不同,请更改 #!/usr/bin/python 以使用该路径。

于 2009-05-24T16:59:07.200 回答
1

提供 Perl 脚本来回答 Python 问题可能有点奇怪,但它对 Python 的工作方式与对 Perl 的工作方式一样。这是一个名为“ fixin”的脚本,意思是“修复解释器”。它将 shebang 行更改为您当前 PATH 的正确字符串。

#!/Users/jleffler/perl/v5.10.0/bin/perl
#
#   @(#)$Id: fixin.pl,v 1.3 2003/03/11 21:20:08 jleffler Exp $
#
#   FIXIN: from Programming Perl
#   Usage: fixin [-s] [file ...]

# Configuration
$does_hashbang = 1;     # Kernel recognises #!
$verbose = 1;           # Verbose by default

# Construct list of directories to search.
@absdirs = reverse grep(m!^/!, split(/:/, $ENV{'PATH'}, 999));

# Process command line arguments
if ($ARGV[0] eq '-s')
{
    shift;
    $verbose = 0;
}
die "Usage: $0 [-s] [file ...]\n" unless @ARGV || !-t;

@ARGV = '-' unless @ARGV;

# Process each file.
FILE: foreach $filename (@ARGV)
{
    open(IN, $filename) || ((warn "Can't process $filename: $!\n"), next);
    $_ = <IN>;
    next FILE unless /^#!/;     # Not a hash/bang file

    chop($cmd = $_);
    $cmd =~ s/^#! *//;
    ($cmd, $arg) = split(' ', $cmd, 2);
    $cmd =~ s!^.*/!!;

    # Now look (in reverse) for interpreter in absolute path
    $found = '';
    foreach $dir (@absdirs)
    {
        if (-x "$dir/$cmd")
        {
            warn "Ignoring $found\n" if $verbose && $found;
            $found = "$dir/$cmd";
        }
    }

    # Figure out how to invoke interpreter on this machine
    if ($found)
    {
        warn "Changing $filename to $found\n" if $verbose;
        if ($does_hashbang)
        {
            $_ = "#!$found";
            $_ .= ' ' . $arg if $arg ne '';
            $_ .= "\n";
        }
        else
        {
            $_ = <<EOF;
:
eval 'exec $found $arg -S \$0 \${1+"\$@"}'
    if \$running_under_some_shell;
EOF
        }
    }
    else
    {
        warn "Can't find $cmd in PATH, $filename unchanged\n" if $verbose;
        next FILE;
    }

    # Make new file if necessary
    if ($filename eq '-') { select(STDOUT); }
    else
    {
        rename($filename, "$filename.bak") ||
            ((warn "Can't modify $filename"), next FILE);
        open(OUT, ">$filename") ||
            die "Can't create new $filename: $!\n";
        ($def, $ino, $mode) = stat IN;
        $mode = 0755 unless $dev;
        chmod $mode, $filename;
        select(OUT);
    }

    # Print the new #! line (or the equivalent) and copy the rest of the file.
    print;
    while (<IN>)
    {
        print;
    }
    close IN;
    close OUT;
}

该代码源自原始 Camel Book(“Programming Perl”,第一版)中的同名脚本。从那时起,这个副本已经被黑客入侵了一些 - 并且应该被黑客攻击更多。但我经常使用它——事实上,我只是将它从一台 Mac 复制到另一台,因为我没有在第二台安装 Perl 5.10.0,所以我运行:

$ perl fixin fixin
Changing fixin to /usr/bin/perl
$

从而从私有安装 Perl 更改为标准安装。

读者练习 - 用 Python 重写脚本。

于 2009-08-02T07:20:35.633 回答