我看到namedtuple的Python语法是:
Point = namedtuple('Point', ['x', 'y'])
为什么它不那么简单:
Point = namedtuple(['x','y'])
它不那么冗长,
答案 0 :(得分:8)
通常,对象不知道它们被分配给哪些变量:
# Create three variables referring to an OrderedPair class
tmp = namedtuple('OrderedPair', ['x','y']) # create a new class with metadata
Point = tmp # assign the class to a variable
Coordinate = tmp # assign the class to another var
这对于命名元组来说是一个问题。我们必须将类名传递给 namedtuple()工厂函数,以便为类提供一个有用的名称,docstring和__repr__,所有这些名称都包含在其中。
这些原因让你感到奇怪的是,普通函数和类定义的处理方式不同。 Python具有def
和class
的特殊语法,它不仅创建函数和类,还分配元数据(名称和文档字符串)并将结果赋给变量。
考虑def
的作用:
def square(x):
'Return a value times itself'
return x * x
关键字def
为您处理好几件事(注意单词" square"将使用两次):
tmp = lambda x: x*x # create a function object
tmp.__name__ = 'square' # assign its metadata
tmp.__doc__ = 'Return a value times itself'
square = tmp # assign the function to a variable
课程也是如此。 class
关键字负责处理多个操作,否则这些操作将重复类名称:
class Dog(object):
def bark(self):
return 'Woof!'
基础步骤重复课程名称(注意单词" Dog"使用两次):
Dog = type('Dog', (object,), {'bark': lambda self: 'Woof'})
命名元组不具备def
或class
等特殊关键字的优势,因此必须先执行自己的步骤。分配给变量的最后一步属于您。如果你考虑一下,命名的元组方式是Python中的标准,而def
和class
是例外:
survey_results = open('survey_results') # is this really a duplication?
company_db = sqlite3.connect('company.db') # is this really a duplication?
www_python_org = urllib.urlopen('http://www.python.org')
radius = property(radius)
你不是第一个注意到这一点的人。 PEP 359建议我们添加一个新关键字make
,该关键字可以允许任何调用者获得def
,class
和import
的自动分配功能。
make <callable> <name> <tuple>:
<block>
将被翻译成作业:
<name> = <callable>("<name>", <tuple>, <namespace>)
最后,Guido并不喜欢&#34; make&#34;提案,因为它引起的问题多于解决的问题(毕竟,它只能让你免于进行单个变量赋值)。
希望能帮助您了解为什么要将类名写入两次。它并不是真的重复。类名的字符串形式用于在创建对象时分配元数据,单独的变量赋值只是为您提供引用该对象的方法。虽然它们通常是同一个名字,但它们不一定是: - )
答案 1 :(得分:2)
班级应该有一个名字并且知道它。并且它没有看到您分配给它的变量,因此它无法使用它。另外,你可以把它称为别的东西,甚至什么都没有:
c = namedtuple('Point', ['x', 'y'])
do_something_with_this(namedtuple('Point', ['x', 'y']))
说到更简单的语法,您也可以这样写:
namedtuple('Point', 'x y')
答案 2 :(得分:2)
namedtuple是一个工厂,返回一个类。只考虑表达式:
namedtuple(['x','y'])
此表达式返回的类的名称是什么?
答案 3 :(得分:1)
因为namedtuple
是一个返回类的函数。为此,它实际上是rendering a string template并且正在调用eval
。要构建字符串,它需要事先获取所有参数。
您需要将相关上下文作为namedtuple
的参数包含在内。如果您不提供类名参数,则需要猜测。编程语言不喜欢猜测。
使用Python语言的规则,此表达式中的namedtuple
函数..
>>> Point = namedtuple(['x','y'])
..无法访问变量名称(Point
),表达式执行后,结果将存储在变量名称中。它只能访问作为参数提供的列表元素(以及之前定义的变量)。