namedtuple的Python语法

use*_*453 5 python namedtuple

我看到namedtuple的Python语法是:

Point = namedtuple('Point', ['x', 'y'])
Run Code Online (Sandbox Code Playgroud)

为什么不这样简单:

Point = namedtuple(['x','y'])
Run Code Online (Sandbox Code Playgroud)

它不那么冗长,

Ray*_*ger 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
Run Code Online (Sandbox Code Playgroud)

这对于命名元组来说是一个问题.我们必须将类名传递给namedtuple()工厂函数,以便为类提供一个有用的名称,docstring和__repr__,所有这些名称都包含在其中.

这些原因让你感到奇怪的是,普通函数和类定义的处理方式不同.Python有特殊的语法defclass这不仅创造了函数和类,但它分配其元数据(名称和文档字符串),并将结果分配给一个变量.

考虑一下def:

def square(x):
    'Return a value times itself'
    return x * x
Run Code Online (Sandbox Code Playgroud)

关键字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
Run Code Online (Sandbox Code Playgroud)

课程也是如此.该class关键字负责多个操作,否则这些操作将重复该类名:

class Dog(object):
    def bark(self):
        return 'Woof!'
Run Code Online (Sandbox Code Playgroud)

基础步骤重复类名称(请注意单词"Dog"使用两次):

Dog = type('Dog', (object,), {'bark': lambda self: 'Woof'})
Run Code Online (Sandbox Code Playgroud)

命名元组没有像一个特殊的关键字的优势,defclass因此它要做的第一件的步骤本身.分配给变量的最后一步属于您.如果你考虑一下,命名的元组方式是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)
Run Code Online (Sandbox Code Playgroud)

你并不是第一个注意到这一点的人.PEP 359建议我们添加一个新的关键字,make即可以允许任何调用获得的自动分配功能def,class以及import.

make <callable> <name> <tuple>:
    <block>
Run Code Online (Sandbox Code Playgroud)

将被转换为作业:

<name> = <callable>("<name>", <tuple>, <namespace>)
Run Code Online (Sandbox Code Playgroud)

最后,Guido不喜欢"make"提案,因为它引起的问题多于它解决的问题(毕竟,它只能让你免于进行单一的变量赋值).

希望能帮助您了解为什么类名被写两次.这不是真的重复.类名的字符串形式用于在创建对象时分配元数据,单独的变量赋值只是为您提供引用该对象的方法.虽然它们通常是同一个名字,但它们不一定是:-)