Nicholas
Nicholas

Reputation: 2668

In Python, can I define a named tuple using typename?

I wonder why the third line in Snippet B would trigger an error. My understanding is in the second line in Snippet B (and A), I created a class variable (not a class instance) cls_obj whose type/class name is Duck. It's like

class Duck(...):
    ...Code goes here

cls_obj=Duck

So I expected snippet A and B would both work, however, snippet B failed! What has gone wrong?

# 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')

Upvotes: 0

Views: 892

Answers (1)

Dietrich Epp
Dietrich Epp

Reputation: 213328

In Python, a class is just a special kind of value.

class Duck(object):
    pass

# 'Duck' is just a variable, you can change it
Duck = 3

x = Duck() # Fails!

You can do things like this:

>>> 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'>

Now that you understand that a class is just a value, everything will start to make more sense. The namedtuple('Goat', ...) isn't the same as class Goat. It defines a class but does not assign the resulting value (the class itself) to a variable at global scope. Functions can't do that, and namedtuple() is an ordinary function.

Upvotes: 1

Related Questions