В Python я могу определить именованный кортеж, используя typename?
Интересно, почему третья строка в фрагменте B вызовет ошибку. Насколько я понимаю, во второй строке фрагмента B (и A) я создал переменную класса (не экземпляр класса) cls_obj
чей тип / имя класса Duck
, Это как
class Duck(...):
...Code goes here
cls_obj=Duck
Поэтому я ожидал, что фрагменты A и B сработают, но фрагмент B потерпел неудачу! Что пошло не так?
# Snippet A
from collections import namedtuple
cls_obj=namedtuple('Duck', 'bill tail')
duck = cls_obj(bill='wide orange', tail='long')
# Snippet B
from collections import namedtuple
cls_obj=namedtuple('Duck', 'bill tail')
duck = Duck(bill='wide orange', tail='long')
1 ответ
Решение
В Python класс - это просто особый вид значения.
class Duck(object):
pass
# 'Duck' is just a variable, you can change it
Duck = 3
x = Duck() # Fails!
Вы можете делать такие вещи:
>>> class Goat(object):
... def __repr__(self):
... return 'Goat()'
...
>>> Cow = Goat
>>> del Goat
>>> Goat()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'Goat' is not defined
>>> Cow()
Goat()
>>> Cow.__name__
'Goat'
>>> Cow().__class__
<class '__main__.Goat'>
Теперь, когда вы понимаете, что класс - это просто значение, все станет более понятным. namedtuple('Goat', ...)
не то же самое, что class Goat
, Он определяет класс, но не присваивает результирующее значение (сам класс) переменной в глобальной области видимости. Функции не могут этого сделать, и namedtuple()
это обычная функция.