2014-09-18 3 views
3

Я хочу сравнить переменную I, установленную в None, которая была элементом строки до, с is, но это не удается.Тип lxml 'None' не является None

Когда я сравниваю эту переменную с None с ==, она работает.

Это переменная Я говорю:

print type(xml.a) -> <type 'lxml.objectify.StringElement'> 

Поскольку некоторые библиотеки, которые я использую имеют None в качестве аргумента по умолчанию (то есть, def f(x=None)), я преобразовал мою nullstrings раньше, как это:

if xml.a == '': 
    xml.a = None 

После этого тип изменился на:

print type(xml.a) -> <type 'lxml.objectify.NoneElement'> 

W Хич не то же самое, как:

print type(None) -> <type 'NoneType'> 

Когда я сравниваю это значение, как я описал выше, я получаю следующий результат:

if xml.a is None: 
    print 'what I expect' 
else: 
    print 'what I do NOT expect' # sadly this one is printed 

if xml.a == None: 
    print 'what I do NOT expect' # this one is printed again... 
else: 
    print 'what I expect' 

Я уже знаю, что при сравнении объектов, которые не тот же экземпляр, isfalse. Но я понимаю, что раньше я установил xml.a экземпляру None. С другой стороны, они не соответствуют их типам, и is возвращает false, поэтому он не может быть в том же экземпляре, что и None.

  • Почему?
  • У меня нет другого выбора, кроме как использовать ==?

Для тех, кто хочет узнать больше о разнице между is и isinstance там была дискуссия об этом here.

+0

После того, что было 'тип (xml.a)' изменен на '<тип 'lxml.objectify.NoneElement'> '? – martineau

+0

После 'xml.a = None'. – WaltheRed

+0

Альтернативный подход заключается в том, чтобы остановить тестирование для None специально и просто искать «ложные» данные, например 'if xml.a'. – tdelaney

ответ

9

Вы используете lxml.objectify API; этот API использует специальный объект для представления значений None в объективированном XML-дереве. Когда вы назначили None на xml.a, lxml сохранили этот специальный объект, чтобы он мог преобразовать его в XML-элемент в документе XML.

У вас есть неNone singleton. Вместо этого у вас есть экземпляр lxml.objectify.NoneElement class.

Вы можете проверить тип этого элемента вместо:

from lxml.objectify import NoneElement 

if isinstance(xml.a, NoneElement): 
+0

Спасибо! Это помогло много! – WaltheRed

+0

Martijn: Итак, 'lxml.objectify' API переименовывает имя «Нет» в нечто другое - потому что, когда я пытаюсь что-то подобное в оболочке Python, я получаю «SyntaxError: не могу назначить None»? – martineau

+1

@martineau: no, присваивание атрибуту дерева 'lxml.objectify' задает конкретный объект типа objectify на основе только что присвоенного значения. Таким образом, присваивание 'None' такому атрибуту обрабатывается в вызове' __setattr__' и сохраняется как 'lxml.objectify.NoneElement'. 'Нет' сам по себе не отскакивает нигде. –

Смежные вопросы