Как Вы организуете модули Python? [закрытый]

Что такое NullPointerException?

Хорошим местом для начала является JavaDocs . Они охватывают это:

Брошено, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:

  • Вызов метода экземпляра нулевого объекта.
  • Доступ или изменение поля нулевого объекта.
  • Выполнение длины null, как если бы это был массив.
  • Доступ или изменение слотов с нулевым значением, как если бы это был массив.
  • Бросать нуль, как если бы это было значение Throwable.

Приложения должны бросать экземпляры этого класса для указания других незаконных видов использования нулевого объекта.

blockquote>

Также, если вы попытаетесь использовать нулевую ссылку с synchronized, который также выдаст это исключение, за JLS :

SynchronizedStatement:
    synchronized ( Expression ) Block
  • В противном случае, если значение выражения равно null, NullPointerException.
blockquote>

Как это исправить?

Итак, у вас есть NullPointerException. Как вы это исправите? Возьмем простой пример, который выдает NullPointerException:

public class Printer {
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    public void print() {
        printString(name);
    }

    private void printString(String s) {
        System.out.println(s + " (" + s.length() + ")");
    }

    public static void main(String[] args) {
        Printer printer = new Printer();
        printer.print();
    }
}

Идентифицирует нулевые значения

. Первый шаг - точно определить , значения которого вызывают исключение . Для этого нам нужно выполнить некоторую отладку. Важно научиться читать stacktrace . Это покажет вам, где было выбрано исключение:

Exception in thread "main" java.lang.NullPointerException
    at Printer.printString(Printer.java:13)
    at Printer.print(Printer.java:9)
    at Printer.main(Printer.java:19)

Здесь мы видим, что исключение выбрано в строке 13 (в методе printString). Посмотрите на строку и проверьте, какие значения равны нулю, добавив протоколирующие операторы или используя отладчик . Мы обнаруживаем, что s имеет значение null, а вызов метода length на него вызывает исключение. Мы видим, что программа перестает бросать исключение, когда s.length() удаляется из метода.

Трассировка, где эти значения взяты из

Затем проверьте, откуда это значение. Следуя вызовам метода, мы видим, что s передается с printString(name) в методе print(), а this.name - null.

Трассировка, где эти значения должны быть установлены

Где установлен this.name? В методе setName(String). С некоторой дополнительной отладкой мы видим, что этот метод вообще не вызывается. Если этот метод был вызван, обязательно проверьте порядок , что эти методы вызывают, а метод set не будет называться после методом печати. ​​

Этого достаточно, чтобы дать нам решение: добавить вызов printer.setName() перед вызовом printer.print().

Другие исправления

Переменная может иметь значение по умолчанию setName может помешать ему установить значение null):

private String name = "";

Либо метод print, либо printString может проверить значение null например:

printString((name == null) ? "" : name);

Или вы можете создать класс, чтобы name всегда имел ненулевое значение :

public class Printer {
    private final String name;

    public Printer(String name) {
        this.name = Objects.requireNonNull(name);
    }

    public void print() {
        printString(name);
    }

    private void printString(String s) {
        System.out.println(s + " (" + s.length() + ")");
    }

    public static void main(String[] args) {
        Printer printer = new Printer("123");
        printer.print();
    }
}

См. также:

Я все еще не могу найти проблему

Если вы попытались отладить проблему и до сих пор не имеете решения, вы можете отправить вопрос для получения дополнительной справки, но не забудьте включить то, что вы пробовали до сих пор. Как минимум, включите stacktrace в вопрос и отметьте важные номера строк в коде. Также попробуйте сначала упростить код (см. SSCCE ).

14
задан Aza 11 April 2013 в 06:28
поделиться

7 ответов

Мой совет:

12
ответ дан 1 December 2019 в 09:13
поделиться

В дополнение к PEP8 и easy_install, необходимо проверить virtualenv. Virtualenv позволяет Вам иметь несколько различных деревьев библиотеки Python. На работе мы используем virtualenv с загружающейся средой для быстрой установки разработки/продуктивной среды, где мы - все в синхронизации w.r.t версии библиотеки и т.д. Мы обычно координируем обновления библиотеки.

5
ответ дан 1 December 2019 в 09:13
поделиться

Существует несколько семейств компонентов Python.

  1. материал, который идет с Python. Это заботится о себе.

  2. материал, который Вы получили с easy_install. Это, также, заботится о себе.

  3. пакеты, что необходимо было получить некоторый другой путь, или как TARballs или как контроль SVN. Создайте Components папка. Поместите загрузки или SVN's там сначала. Каждый Раз. Сделайте установки оттуда.

  4. пакеты, что Вы записали, что являются допускающими повторное использование. Я имею Projects папка с каждым проектом в той папке. Если проект является очень допускающей повторное использование вещью, он имеет setup.py, и я на самом деле выполняю установку, как будто я загрузил его. У меня нет многих из них, но некоторых. Некоторые из них могли бы стать проектами с открытым исходным кодом.

  5. заключительные приложения Вы пишете. У меня есть папка в Projects с каждым из этих приложений верхнего уровня. Они - обычно большие, хаотичные вещи (как сайты Django) и не имеют setup.py. Почему? Они часто довольно сложны только с несколькими установками сервера для управления, и каждая из тех установок сервера уникальна. Они обычно полагаются PYTHONPATH для идентификации их частей.

Уведомление общая тема. Или они - Компоненты, которые Вы загрузили, или они - Проекты, Вы продолжаете работать.

кроме того, я разделяю это (до степени) от клиента. У меня есть основной каталог папок Client, каждая из которых имеет Проекты и каждый проект, имеет Продажи и Доставку. Не все проекты имеют обе продажи и доставку.

5
ответ дан 1 December 2019 в 09:13
поделиться

"Модули" страница документации Python является полезным руководством по организации кода, конкретно разделы "пакетов"

1
ответ дан 1 December 2019 в 09:13
поделиться

Возможно PEP8 и easy_install может помочь Вам?

2
ответ дан 1 December 2019 в 09:13
поделиться

Я сохраняю весь источник для своих пакетов внутри ~/Packages/, и затем я делаю стандартную установку с "установкой python2.5 setup.py" на них. Это бросает в (для меня)/Library/Frameworks/Python/Versions/current/lib/python2.5/site-packages/. Для разработки моего собственного программного обеспечения у меня есть псевдонимы, настроенные для переключения между соединительной линией / ответвлений/1.0, и т.д., pre-prending на PYTHONPATH. (Я должен работать 'setup.py build_ext - оперативный' в каждом из этих каталогов, прежде чем они импортируют правильно.)

стоит отметить, что Python2.6 имеет каталог пакетов сайта в расчете на пользователя, который можно найти более удобным.

2
ответ дан 1 December 2019 в 09:13
поделиться

Мой совет состоит в том, чтобы попытаться поместить все в Ваш каталог (каталоги) пакетов сайта, если у Вас нет серьезного основания не к. И я стараюсь избегать easy_install, потому что я нахожу, что он ухаживает к хламу за моим sys.path с местоположениями яйца, но это - просто я. Некоторые люди находят это полезным.

, Если у Вас есть много программ, которые пользуются различными библиотеками, которые могут конфликтовать друг с другом, можно также хотеть проверить virtualenv.

1
ответ дан 1 December 2019 в 09:13
поделиться
Другие вопросы по тегам:

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