Зачем инициализировать переменную Python значением None, а затем присвоить ей реальное значение? - PullRequest
0 голосов
/ 19 апреля 2019

То есть, каково значение pub = None в приведенном ниже? Когда и почему это хорошая практика?

counter = 0
pub = None

def callback_receive_number_data(msg):
    global counter
    counter += msg.data
    new_msg = Int64()
    new_msg.data = counter
    pub.publish(new_msg)

sub = rospy.Subscriber('/number', Int64, callback_receive_number_data)
pub = rospy.Publisher('/number_count', Int64, queue_size=10)

Ответы [ 3 ]

2 голосов
/ 19 апреля 2019

Поиск кода в Google привел меня к этой странице , которая разбивает каждую строку кода.

В отношении указанного выше раздела на сайте указывается:

Мы инициализируем как глобальный счетчик, так и издателя. Если мы хотим использовать их во всех функциях программы, мы должны объявить их в глобальном масштабе, что далеко от оптимального. Позже мы увидим, что Код ООП решит эту проблему.

Короче говоря, это способ объявить переменную, не назначая ей ничего. Если бы это была строка, вы могли бы объявить ее как some_string = "", но, поскольку pub является «издателем», это просто более простой способ объявить ее для последующего использования в коде.

1 голос
/ 19 апреля 2019

В основном я делаю это, чтобы моя среда IDE не кричала мне, что переменная может быть необъявленной.В приведенном выше примере, если у вас не было строки pub = None, некоторые редакторы, стараясь быть умными, выделят строку pub.publish(new_msg) и скажут, что «pub не может быть объявлен!»или что-то типа того.Это не проблема, если во время выполнения будет существовать pub до вызова этой функции.Редактор не может понять это, просто взглянув на ваш код (по крайней мере, не просто), поэтому, чтобы избежать предупреждения, проще просто убедиться, что pub существует в пространстве имен перед его использованием.

0 голосов
/ 19 апреля 2019

Строка pub = None не нужна. может быть полезным, но с остальным кодом, как написано, это не так.

Проблема в том, что вы пишете функцию, которая ожидает глобальной переменной pub, для которой будут вызываться определенные методы. Этот код потерпит неудачу, если pub не определено. К сожалению, также потерпит неудачу, если pub равно None (просто по-другому).

Теперь это, вероятно, не проблема, если функция не вызывается до того, как pub получит реальное значение. Но в этом коде функция действительно передается в качестве обратного вызова на rospy.Subscriber до переназначения pub, поэтому (не зная ничего о rospy), она теоретически может быть вызвана немедленно, до следующего линия на верхнем уровне проходит, давая pub реальное значение.

Есть несколько способов улучшить ситуацию. Во-первых, вы можете определить pub, прежде чем делать что-нибудь с callback_receive_number_data. Попробуйте просто поменять местами порядок последних двух строк, чтобы сначала определить pub, а затем sub (с функцией в качестве обратного вызова).

Во-вторых, вы можете добавить код обработки ошибок в функцию обратного вызова, чтобы определить, когда pub еще не определено. Это позволило бы функции вести себя контролируемым образом, если в pub нет подходящего значения. Для этого подхода было бы полезно присваивать pub = None, так как в переменной легче обнаружить неверное значение, чем когда переменная полностью отсутствует. Но этот подход может также подавлять реальные ошибки, поэтому я бы пошел на это, только если вы уверены, что есть хороший способ обработки ошибок в любой ситуации (вместо сбоя с трассировкой, которая, мы надеемся, укажет программисту на ошибку) .

...