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

제 목표는 이전 목록 (이 예에서는 책 목록이고 속성 중 하나는 제목 또는 장르 또는 가격)에 대한 속성 목록을 인쇄하는 제네릭 함수를 작성하는 것입니다. 파이썬 3.3에서 이것을 할 수 있습니까?Python 3.3에서 이전 목록의 속성 목록을 인쇄하는 제네릭 함수를 작성하는 방법은 무엇입니까?

보관할 점점 오류 : attribute 이후

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

이 매개 변수

print(i.attribute) 

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

속성 이름을 동적으로 사용하려는 경우 'dict'(또는 'dict'을 상속하거나 사용하는 클래스) 대신 'namedtuple'을 사용하는 이유는 무엇입니까? 'namedtuple'의 요점은 당신에게 _static_ 속성을주는 것입니다. 소스 코드에 이름을 붙임으로써 찾을 수 있습니다. – abarnert

+0

또 어떤 이유에서'namedtuple'을 실제로 해체해야 할 필요가 있다면,'i_fields'라는 이름의 속성 명 목록에 언제나 액세스 할 수 있습니다. 아니면'i._asdict()'를 사용하여'OrderedDict'로 변환 할 수 있습니다. . – abarnert

답변

2

변경, 당신은 getattr를 사용하여 객체의 속성을 추출 할 필요가 대신 단지 일 i.attribute. karthikr에 의해 설명 된 바와 같이

1

이름으로 속성을 찾는위한 범용 솔루션은 getattr된다 getattr(i, 'foo')i.foo과 동일하고, getattr(i, attribute)는 문자 그대로 'foo'만큼 쉽게 동적 문자열을 사용할 수 있습니다.

특별히 namedtuple을 다루는 경우 몇 가지 방법으로 필드 - 인덱스 매핑에 액세스 할 수 있습니다. 예를 들어 i._fields은 필드의 (정렬 된) 목록을 제공하고 i._asdict()OrderedDict과 동일한 값을 제공하므로 d = i._asdict()을 입력 한 다음 d[attribute]을 입력하면됩니다.

그러나이 모든 것이 처음에는 namedtuple을 사용하는 이유에 대한 질문을 제기합니다. 일반적으로 속성 액세스의 전체 지점 인 namedtuple정적 인의 속성에 액세스하기에 적합하다는 것입니다. 속성 이름은 소스 코드의 일부입니다. 이 방법을 사용하면 변수 집합을 동적으로 생성하는 것과 비슷합니다. 이는 herehere으로 설명되어 있습니다.

방금로부터 상속 또는 소유 한 클래스 -OR dict을 사용하면 한이 자신의 이름으로 일을 찾는 것은 동적으로 dict이 모든 것 때문에, 사소한 것 : i[attribute].

그리고 클래스가 없어도 나머지함수를 작성하여 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이 작업에 적합한 도구입니다.

+0

모든 답변과 매우 유용한 참고 자료를 제공해 주셔서 감사합니다. : D 내 수업 과제의 일부로 "namedtuple"을 사용해야합니다. 우리는 아직 사전에 관해 가르쳐지지 않았습니다. 어쨌든 다시 답변을 보내 주시면 감사하겠습니다. –

+0

@TrungNguyen : 선생님이'dict' 전에'namedtuple'에 대해 가르쳐 줬나요? 진심으로? 새로운 교사가 필요할 수도 있습니다 ... – abarnert

+0

@TrungNguyen 'dict' 수업을 놓치지 않았습니까? – karthikr