tidyverse error for dependencies 'метла', 'modelr' недоступны [дублировать]

Python: Mutable Default Argument

Аргументы по умолчанию получают оценку во время компиляции функции в объект функции. При использовании этой функции, несколько раз с помощью этой функции, они являются и остаются одним и тем же объектом.

Когда они изменяются, когда они мутируются (например, добавляя к нему элемент), они остаются мутированными по последовательным вызовам.

Они остаются мутированными, потому что каждый раз они являются одним и тем же объектом .

Эквивалентный код:

Поскольку список связан с функцией, когда объект функции компилируется и инстанцируется, это:

def foo(mutable_default_argument=[]): # make a list the default argument
    """function that uses a list"""

почти точно эквивалентно этому:

_a_list = [] # create a list in the globals

def foo(mutable_default_argument=_a_list): # make it the default argument
    """function that uses a list"""

del _a_list # remove globals name binding

Демонстрация

Вот демонстрация - вы можете проверить, что они являются одним и тем же объектом каждый раз, когда они ссылаются на

  • , увидев, что список создан до того, как функция завершила компиляцию объекту функции,
  • , заметив, что идентификатор один и тот же каждый раз, когда список ссылается,
  • , наблюдая, что список остается, когда функция, которая его использует, называется второй раз,
  • , наблюдая порядок, в котором вывод печатается из источника (который я удобно пронумеровал для вас):

example.py

print('1. Global scope being evaluated')

def create_list():
    '''noisily create a list for usage as a kwarg'''
    l = []
    print('3. list being created and returned, id: ' + str(id(l)))
    return l

print('2. example_function about to be compiled to an object')

def example_function(default_kwarg1=create_list()):
    print('appending "a" in default default_kwarg1')
    default_kwarg1.append("a")
    print('list with id: ' + str(id(default_kwarg1)) + 
          ' - is now: ' + repr(default_kwarg1))

print('4. example_function compiled: ' + repr(example_function))


if __name__ == '__main__':
    print('5. calling example_function twice!:')
    example_function()
    example_function()

и работает это с python example.py:

1. Global scope being evaluated
2. example_function about to be compiled to an object
3. list being created and returned, id: 140502758808032
4. example_function compiled: 
5. calling example_function twice!:
appending "a" in default default_kwarg1
list with id: 140502758808032 - is now: ['a']
appending "a" in default default_kwarg1
list with id: 140502758808032 - is now: ['a', 'a']

Означает ли это нарушение принципа «Наименьшее удивление»?

Этот порядок выполнения часто путает новых пользователей Python. Если вы понимаете модель исполнения Python, это становится вполне ожидаемым.

Обычная инструкция для новых пользователей Python:

Но поэтому обычная инструкция для новых пользователей заключается в том, чтобы вместо этого создать свои аргументы по умолчанию:

def example_function_2(default_kwarg=None):
    if default_kwarg is None:
        default_kwarg = []

Это использует None singleton как объект-дозор, чтобы сообщить функции, есть ли у нас аргумент, отличный от значения по умолчанию. Если мы не получаем никакого аргумента, то мы действительно хотим использовать новый пустой список [] в качестве значения по умолчанию.

Как говорится в разделе в разделе управления потоком :

Если вы не хотите, чтобы по умолчанию были разделены между последующими вызовами, вы можете написать такую ​​функцию, как это:

def f(a, L=None):
    if L is None:
        L = []
    L.append(a)
    return L
31
задан Andrew Redd 10 June 2011 в 06:10
поделиться

7 ответов

Для семейства Debian / Ubuntu мы обычно рекомендуем

 $ sudo apt-get install r-base-dev

, поскольку он извлекает все пакеты, которые обычно необходимы для компиляции. И этот подход все время тестируется, так как на это полагаются автоматизированные разработчики пакетов (а также дополнительные встроенные сборки для каждого пакета). Пакет gfortran также указан здесь; возможно, у вас есть неработающая ссылка из предыдущей установки, поэтому я также попробую dpkg --purge gfortran; apt-get install gfortran. Тем не менее, десятки пакетов R (и самого R) используют Fortran, поэтому здесь не должно быть никакой магии.

24
ответ дан Dirk Eddelbuettel 21 August 2018 в 02:45
поделиться
  • 1
    Дирк, как правило, ваш совет на месте, но что-то смешное происходит с конфигурацией здесь. В вопросе я показываю сообщения сборки. gfortran найден и используется для компиляции delcol.f успешно, но затем снова ссылки gfortran, который он не может найти. – Andrew Redd 10 June 2011 в 15:05
  • 2
    Не случайно ли вы столкнулись с символическими связями между различными версиями gcc-*, g++-* и gfortran-* и / или их эквивалентами библиотек? «Что-то смешное» иногда является простой ошибкой оператора. На моем поле libgfortran.so.3 живет в /usr/lib/x86_64-linux-gnu/ и идет из пакета libgfortran3. – Dirk Eddelbuettel 10 June 2011 в 15:11
  • 3
    Да, это то же самое для меня. Возникла проблема с ссылкой /usr/lib/libgfortran.so, как только было правильно указать на /usr/lib/x86_64-linux-gnu/libfortran.so.3.0.0, все снова работает. – Andrew Redd 10 June 2011 в 17:33
  • 4
    Осторожный. У моего Ubuntu 11.04 нет ссылки /usr/lib/libgfortran.so. Попробуйте ldconfig -p | grep libgfortran, и он должен показать, что libgfortran.so.3 найден из каталога /usr/lib/x86_64-linux-gnus. Или еще моя (довольно новая) коробка на работе отключена :) – Dirk Eddelbuettel 10 June 2011 в 17:38
  • 5
    Установка r-base-dev сделала трюк для меня, на ubuntu, с той же ошибкой, что и OP – pocketfullofcheese 6 February 2013 в 21:29

Для будущих утерянных душ также помогает проверять версии всех компиляторов (за https://askubuntu.com/questions/276892/cannot-find-lgfortran ). В моем случае gcc и gfortran были равны 4.8.4, но g ++ - 4.6.

0
ответ дан Community 21 August 2018 в 02:45
поделиться

Похоже, что другие предложения уже исправили вашу проблему, но ваш вопрос также применился ко мне, но в моем случае решение было другим. Моя проблема заключалась в том, что мои версии gcc и g ++ отличались от моей версии gfortran. Я использовал следующее, чтобы переключать их так, чтобы они были одинаковыми.

  1. Проверьте, какая у вас версия gcc, g ++ и gfortran:
    g++ --version
    gcc --version
    gfortran --version
    
  2. Сопоставьте их так что они все одинаковы:
    sudo update-alternatives --config g++
    sudo update-alternatives --config gcc
    sudo update-alternatives --config gfortran
    

В моем случае у меня была только одна версия gfortran, поэтому я просто изменил версии g ++ и gcc в соответствии с версией gfortran.

10
ответ дан dlpolanco 21 August 2018 в 02:45
поделиться
  • 1
    Обратите внимание, что точное совпадение может не потребоваться: установка gcc на 5.4.1 заставляла его работать для gfortran 6.2.0. – Evpok 14 February 2017 в 09:59

Я использую Centos, и я не могу получить r-base-dev. Я также установил gfortran, и его версия совпадает с версией gcc и g ++; он все еще не работает. Однако я решил эту проблему, создав ~/.R/Makevars, используя

cd ~
mkdir .R
touch Makevars

. Я нашел каталог, в котором я установил gfortran (видимо, проблема в том, что R не может его найти) с помощью

which gfortran

Он сказал, что я установил gfortran в usr/bin/gfortran. Затем я добавил флаги в .R/Makevars, чтобы сказать R:

F77 = /usr/bin/gfortran
FC = $F77
FLIBS = -L/usr/bin/gfortran

Вы можете редактировать файл Makevars таким образом:

vi .R/Makevars

Теперь вы ввели vi, которая может редактировать текстовые файлы. Введите i для редактирования; вы увидите INSERT в нижней части окна терминала. Затем вы можете ввести то, что я поставил выше. Чтобы сохранить изменения и выйти из vi, нажмите клавишу esc и введите :wq.

Я не совсем уверен, правильно ли вставил линию FLIBS, так как для MacOS это совсем другое. В MacOS есть каталог под gfortran, для которого есть ссылки на библиотеки, но, по-видимому, gfortran не является каталогом в Linux. По крайней мере, это сработало для меня, а также решило проблему /usr/bin/ld: cannot find -lquadmath, поэтому я установил R-пакеты, требующие gfortran плавно.

1
ответ дан Dongyi Lu 21 August 2018 в 02:45
поделиться

У меня была такая же проблема при попытке установить пакет CRAN VGAM на Ubuntu 12.10 64bit. У меня уже установлен r-base-dev, но второй ответ Эндрю Редда на ответ Дирка Эддельбуэттеля сработал для меня.

В частности, я получал две ошибки:

/usr/bin/ld: cannot find -lgfortran
/usr/bin/ld: cannot find -lquadmath

которые были исправлены строками:

sudo ln -s /usr/lib/x86_64-linux-gnu/libgfortran.so.3 /usr/lib/libgfortran.so
sudo ln -s /usr/lib/x86_64-linux-gnu/libquadmath.so.0 /usr/lib/libquadmath.so

Обратите внимание, что только первая строка будет необходимо позаботиться о проблеме с исходного поста. Вторая строка исправлена ​​моей дополнительной ошибкой с lquadmath.

52
ответ дан kevin 21 August 2018 в 02:45
поделиться
  • 1
    Работал для меня. Благодарю. – Björn Jacobs 30 September 2013 в 17:36
  • 2
    Мне кажется, что libgfortran3-dev отсутствует на Ubuntu 13.10; есть такие пакеты для более новых версий, но для R (из официальных пакетов Ubuntu), похоже, нужно связать с libgfortran.so.3. Другими словами, я только получил это, чтобы работать с этим руководством symlinking решение, потому что установка r-base-dev (и, следовательно, gfortran-пакетов) не хватало. – hans_meine 5 December 2013 в 19:03
  • 3
    тоже помог мне, спасибо! – fabians 1 December 2014 в 14:20
  • 4
    То же самое касается Ubuntu 14.04, я снова попробовал предложение Дирка (вероятно, разумно регулярно обновлять R!) – Louis Maddox 17 August 2015 в 20:33
  • 5
    Работал и для меня! – NoBackingDown 9 February 2017 в 22:30

Такая же проблема при установке R-пакета minqa на ubuntu 12.04, R3.1.0., x86 32bits (на самом деле это была часть установки пакета каретки).

Решено

sudo ln -s /usr/lib/i386-linux-gnu/libgfortran.so.3 /usr/lib/libgfortran.so

r-base-dev переустановка не работает, и я не пытался переустановить gfortran из-за всех зависимостей.

В зависимости от системы / версии,

ls -l /usr/lib/libgfortran.so

проверяет, что ссылка существует / права.

6
ответ дан Ogaga Uzoh 21 August 2018 в 02:45
поделиться
  • 1
    такая же история для меня на debian с пакетом igraph. – fabians 1 December 2014 в 14:22
  • 2
    Обратите внимание, что на некоторых машинах вам может понадобиться запустить sudo ln -s /usr/lib/x86_64-linux-gnu/libgfortran.so.3 /usr/lib/libgfortran.so (это то, что сработало для меня в Linux Mint 18.3) – seaotternerd 12 July 2018 в 00:24

Если вы используете gcc44, вам понадобятся:

yum install gcc44-gfortran
0
ответ дан user4020650 21 August 2018 в 02:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: