1
from collections import namedtuple
Book = namedtuple('Book', 'author title genre year price instock')

BSI = [
    Book("JK Rowling", "Harry Potter", "Fantasy", 1997, 10.00, 50),
    Book("Harper Lee", "To Kill a Mockingbird", "Fiction", 1960, 15.00, 100),
    Book("Dan Brown", "Da Vinci Code", "Thriller", 2003, 20.00, 500),
    Book("Mr. Python", "How to Python", "Technology", 2010, 40.00, 10),
    Book("Stephen King", "It", "Horror", 1986, 50.00, 10),
    Book("Some Guy", "Time Traveling", "Technology", 2020, 800.00, 256)
]

def Book_collection_attribute (BSI: list, attribute: str) -> list:
    '''Print out the list of the specific attribute of the list of Book collection'''
    for i in BSI:
        print(i.attribute)
    return BSI
    print(Book_collection_attribute(BSI,'title'))

私の目標は、前のリストの属性のリストを出力する汎用関数を作成することです (この例では、本のリストとその属性の 1 つ: タイトル、ジャンル、価格)。Python 3.3でこれを行うことはできますか?

エラーが発生し続ける:

Traceback (most recent call last):
  File "C:\Users\ntt2k\Desktop\ICS 31\lab3.py", line 133, in <module>
    print(Book_collection_attribute(BSI,'title'))
  File "C:\Users\ntt2k\Desktop\ICS 31\lab3.py", line 131, in Book_collection_attribute
    print(i.attribute)
AttributeError: 'Book' object has no attribute 'attribute'
4

2 に答える 2

2

変化する

print(i.attribute)

print(getattr(i, attribute)) 
#or if you want to specify a default, 
#print(getattr(i, attribute, ''))

はパラメータであるため、 を実行する代わりに をattribute使用してオブジェクトの属性を抽出する必要があります。getattri.attribute

于 2013-10-17T17:56:43.993 に答える
1

名前で属性を検索するための汎用ソリューションは、karthikr で説明されているように、getattr:getattr(i, 'foo')と同じi.fooでありgetattr(i, attribute)、リテラルと同じくらい簡単に動的文字列を使用できます'foo'

特に s を扱っている場合namedtupleは、いくつかの異なる方法でフィールドからインデックスへのマッピングにアクセスできます。たとえば、i._fieldsはフィールドの (順序付けられた) リストをi._asdict()提供しますが、 は と同じ値を提供するOrderedDictため、 を実行してd = i._asdict()からd[attribute].

namedtupleただし、これらすべてにより、そもそもなぜ a を使用しているのかという疑問が生じます。一般に、特に属性アクセスのポイントは、その属性への静的namedtupleアクセスに最適であるということです。属性名はソースコードの一部です。このように使用することは、一連の変数を動的に作成することに似ています。これは、こちらこちらで説明されているように、悪い考えです。

a を使用しただけの場合、dictまたは a を継承または所有するクラスを使用した場合、これは簡単です。名前で動的に検索することが a のdictすべてであるためですi[attribute]

また、クラスがなくても、 を作成するbook関数を作成できるdictので、コードの残りの部分も見栄えがよくなります。例えば:

def book(author, title, genre, year, price, instock):
    return {'author': author, 'title': title, 'genre': genre, 
            'year': year, 'price': price, 'instock': instock}

namedtupleこれをあなたによって生成されたコード ( として表示されます) と比較すると、Book.sourceはるかに単純です。その繰り返しが気に入らない場合は、いつでもこれを行うことができます。

def book(*args):
    return dict(zip('author title genre year price instock'.split(), args))

もちろん、ほとんどの場合、属性に静的にアクセスしたい場合もありますが、動的にアクセスしたい場合もあります。その場合、getattrまさにその仕事に適したツールです。

于 2013-10-17T18:09:09.140 に答える