Вызывается неправильный интерпретатор Python

Я обновил свой интерпретатор 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 и не очень хорошо знаком с интерпретируемыми языками, поэтому я не слишком уверен, что происходит.

Редактировать: Вау, это было быстро. Большое спасибо!


person Lucas    schedule 24.05.2009    source источник


Ответы (6)


Согласно первой строке скрипта, #!/usr/bin/python, вы вызываете интерпретатор Python по адресу /usr/bin/python (который, скорее всего, входит в состав Mac OS X). Вы должны изменить этот путь на путь, по которому вы установили интерпретатор Python 3 (вероятно, /usr/local/bin/python или /opt/local/bin/python); или вы можете просто изменить эту строку на #!/usr/bin/env python, которая будет вызывать python, указанную первой в вашей переменной PATH (которая, по-видимому, является более новой версией, которую вы установили).

person mipadi    schedule 24.05.2009

Во-первых, рекомендуемая строка shebang:

#!/usr/bin/env python

Это гарантирует, что интерпретатор python, который вызывается, когда вы ./foo.py, является тем же интерпретатором, который вызывается, когда вы вызываете python из командной строки.

Судя по вашему описанию, я подозреваю, что если бы вы это сделали:

which python

Это не даст вам /usr/bin/python. Это дало бы вам что-то еще, где живет интерпретатор Python 3. Вы можете либо изменить свою строку shebang на указанную выше, либо заменить путь к интерпретатору python на путь, возвращаемый which.

person freespace    schedule 24.05.2009

Попробуйте which python. Я расскажу вам, какой интерпретатор Python используется в вашей среде. Если это не /usr/bin/python как в скрипте, то ваше подозрение подтверждается.

person bbuser    schedule 24.05.2009

Очень возможно, что вы подозреваете, что линия shebang вызывает старую версию. Две вещи, которые вы, возможно, захотите проверить:

1) какая версия интерпретатора в /usr/bin/python:

/usr/bin/python -V

2) где установленный вами интерпретатор python 3:

which python

Если вы получили правильный из командной строки, замените строку shebang на это:

#!/usr/bin/env python

Дополнение: вы также можете заменить старую версию python символической ссылкой на python 3, но имейте в виду, что любые крупные обновления 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
person EvanK    schedule 24.05.2009
comment
Вероятно, не лучшая идея заменять /usr/bin/python символической ссылкой. Некоторые утилиты OS X могут ссылаться на /usr/bin/python, и, поскольку Python 3K не на 100% обратно совместим с Python 2.x, вы рискуете сломать некоторые из этих утилит. - person mipadi; 24.05.2009
comment
Да, я бы рекомендовал не связываться с Python, который поставляется с OS X. - person Jason Baker; 24.05.2009
comment
Я бы особенно рекомендовал не заменять системный python намеренно несовместимой версией (будучи python 3.x) - person Arafangion; 08.06.2012
comment
@mipadi: Вы говорите, что рискуете сломать некоторые из этих утилит... Это не совсем так... Вы фактически гарантируете, что эти утилиты сломаются, это не простой риск! Вся предпосылка python 3.x заключалась в том, чтобы нарушить совместимость. - person Arafangion; 08.06.2012

запустите 'what python' - если это дает другой ответ, чем /usr/bin/python, измените #!/usr/bin/python, чтобы вместо этого указать этот путь.

person Nathaniel Flath    schedule 24.05.2009

Может быть немного странно предоставлять 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.

person Jonathan Leffler    schedule 02.08.2009