kwargs

2016-03-01 11 views
5

kabul namedtuple olun.kwargs

from collections import namedtuple 

Person = namedtuple('Person', 'name') 
p = Person(name='joe', age=25) 

# Traceback (most recent call last): 
# File "python", line 1, in <module> 
# TypeError: __new__() got an unexpected keyword argument 'age' 

nasıl kwargs yüzden güvenle ekstra argümanlar iletebilirsiniz kabul namedtuple yapabilirsiniz: Bir namedtuple varsa Ama `beklenmedik kelime argüman alırsınız?

+1

Sorununuzu düzeltme için ossible çözüm Bunu yapamazsın. –

+0

İsimdeki ipuçları. –

+0

@Alex, benim sorum ile ne ilgisi var? – norbertpy

cevap

7

Yorumlayıcıda aşağıdaki oturum bir p gösterir

Python 3.5.0 (v3.5.0:374f501f4567, Sep 13 2015, 02:27:37) [MSC v.1900 64 bit (AMD64)] on win32 
Type "copyright", "credits" or "license()" for more information. 
>>> import collections 
>>> class Person(collections.namedtuple('base', 'name')): 
    __slots__ =() 
    def __new__(cls, *args, **kwargs): 
     for key in tuple(kwargs): 
      if key not in cls._fields: 
       del kwargs[key] 
     return super().__new__(cls, *args, **kwargs) 


>>> p = Person(name='joe', age=25) 
>>> p 
Person(name='joe') 
>>> 

Alternatif:: Bunun yerine daha basit bir çözüm olduğundan

, istediğiniz şekilde daha sonraki programı bulabilirsiniz:

#! /usr/bin/env python3 
import collections 


def main(): 
    Person = namedtuple('Person', 'name') 
    p = Person(name='joe', age=25) 
    print(p) 


def namedtuple(typename, field_names, verbose=False, rename=False): 
    base = collections.namedtuple('Base', field_names, verbose, rename) 
    return type(typename, (base,), { 
     '__slots__':(), 
     '__new__': lambda cls, *args, **kwargs: base.__new__(cls, *args, **{ 
      key: value for key, value in kwargs.items() 
      if key in base._fields})}) 


if __name__ == '__main__': 
    main() 
+0

İhtiyacım olan her sınıf için '__new__' yöntemini yazmak istersem, o zaman ilk örneğim gibi bir ders yapacağım. Ama cevabın için teşekkürler. – norbertpy

+0

@norbertpy Bu sorunu otomatik olarak sizin için otomatik olarak halletmek için 'namedtuple' adlı yeni bir uygulama ekledim. İlk örnekle aynı şeyi yapar, ancak değişikliği "__new__" olarak işler, böylece kodu kendiniz yazmayı engelleyebilirsiniz. –

+0

__slots__' olmadan adlandırılmış alt sınıfın alt sınıflarını yapmayın. Hafızayı kaybeder. – ppperry

6

Güzel değil:

from collections import namedtuple 
Person = namedtuple('Person', 'name') 

def make_person(*args, **kwargs): 
    person_args = {} 

    # process positional args 
    if len(args) > len(Person._fields): 
     msg = "Person() takes %d positional arguments but %d were given" % (len(Person._fields), len(args)) 
     raise TypeError(msg) 
    for arg_name, arg_value in zip(Person._fields, args): 
     person_args[arg_name] = arg_value 

    # process keyword args 
    for arg_name, arg_value in kwargs.items(): 
     try: 
      i = Person._fields.index(arg_name) 
     except ValueError: 
      pass # ignore arguments not defined as Person fields 
     else: 
      if arg_name in person_args: 
       msg = "make_person() got multiple values for argument " + repr(arg_name) 
       raise TypeError(msg) 
      person_args[arg_name] = arg_value 

    if len(person_args) != len(Person._fields): 
     msg = "Person() requires additional arguments: " 
     msg += ", ".join([repr(x) for x in Person._fields if x not in person_args]) 
     raise TypeError(msg) 
    return Person(*[person_args[x] for x in Person._fields]) 

yukarıda Verilen:

p = Person(*(dict(name='joe', age=25)[k] for k in Person._fields)) 
2

mümkündür Person namedtuple alanlarında olarak tanımlanmamış argümanları göz ardı etmek Person sınıfı yapıcısı sarmak için:

>>> make_person('a') 
Person(name='a') 
>>> make_person('a', b='b') 
Person(name='a') 
>>> make_person('a', name='b') 
TypeError: make_person() got multiple values for argument 'name' 
>>> make_person(b='b') 
TypeError: Person() requires additional arguments: 'name' 
>>> make_person(1, 2) 
TypeError: Person() takes 1 positional arguments but 2 were given 
+0

Paul'un cevabından farklı olarak, bu cevap konumsal ve anahtar kelime bağımsız değişkenlerini doğru şekilde birleştirmeyi ve tüm hata durumlarını bilgilendirici hata mesajlarıyla düzgün bir şekilde ilgilenmeyi destekler. – taleinat

İlgili konular