2012-07-19 6 views
4

저는 Python과 OOP의 새로운 기능을 일반적으로 사용합니다. "...instance has no attribute '__getitem__'"에 오류가 있으며 작성한 개체가 목록이 아니라는 것을 알고 있습니다. 어떻게하면 목록 객체가 될 수 있습니다. 여기서, 클래스 파일이다목록 개체를 만드는 방법은 무엇입니까? 인스턴스에 '__getitem__'속성이 없습니다.

#!/usr/bin/python -tt 

import math, sys, matrix, os 

class Point: 
    'Class for points' 
    pointCount = 0 

    def __init__(self, x, y, z): 
     'initialise the Point from three coordinates' 
     self.x = x 
     self.y = y 
     self.z = z 
     Point.pointCount += 1 

    def __str__(self): 
     'print the Point' 
     return 'Point (%f, %f, %f)' %(self.x, self.y, self.z) 

    def copyPoint(self, distance): 
     'create another Point at distance from the self Point' 
     return Point(self.x + distance[0], self.y + distance[1], self.z + distance[2]) 

    def __del__(self): 
     'delete the Point' 
     Point.pointCount -= 1 
     #print Point.pointCount 
     return '%s deleted' %self 

I는 (X, Y, Z) 안에 3 개 개의 좌표 점으로 있어야하고, 이들 좌표는 []로 목록 인스턴스 같은 "호출"이어야한다.

비슷한 주제를 읽었지만 많이 이해하지 못했습니다. 간단한 단어와 예를 들어 설명하십시오.

def __getitem__(self, item): 
    return (self.x, self.y, self.z)[item] 

이것은 X, Y 및 Z의 tuple 구축 한 액세스 파이썬 자체의 인덱싱 기능을 사용

+0

거리로 무엇을 전달합니까? 뭔가 색인을 달 수 있습니까? 실제로'Point'를리스트 (예 : point [0]'등)로 사용하려고합니까? –

+1

답변은 제목에 있습니다. – Marcin

+1

__getitem__ : http : // stackoverflow를 구현해야합니다.com/questions/2936863/python-implementation-slicing-in-getitem –

답변

1

나는 당신이 그것의 서브 클래스 만들 것입니다 collections.namedtuple 공장 기능을 사용하여 Point 클래스를 만드는 것을 고려 제언 내장 tuple 클래스입니다. 그러면 보일러 판 작업을 줄일 수 있습니다. namedtuple 클래스에는 이름으로 액세스 할 수있는 속성 (예 : p.x)과 p[0]과 같은 색인 된 속성이 있습니다.

그들은 또한 매우 많은 클래스 인스턴스가있을 경우 중요 할 수있는 tuple과 같이 매우 효율적입니다.

서브 클래 싱하여 반환되는 내용을 전문화하거나 옵션을 사용하여 소스 코드를 캡처하고 필요에 따라 수정할 수 있습니다.

위의 문서에 2D Point 클래스를 만드는 데 사용 된 것을 보여주는 예가 있는데, 이는 특정 사용 사례에서 매우 유용 할 수있는 것처럼 보입니다.

여기에 하나가 서브 클래스를 통해 사용자 정의 3D Point 클래스를 정의 할 수있는 방법을 보여주는 예입니다 :

from collections import namedtuple 

class Point(namedtuple('Point', 'x y z')): 
    __slots__ =() # prevent creation of instance dictionaries to save memory 
    point_count = 0 # instance counter 

    def __init__(self, *args): 
     super(Point, self).__init__(*args) 
     Point.point_count += 1 

    def distance(self, other): 
     return sum((self[i]-other[i])**2 for i in xrange(len(self))) ** 0.5 

    def copy_point(self, distance): 
     'create another Point at distance from the self Point' 
     return Point(*[dimension+distance for dimension in self]) 

p1 = Point(0, 0, 0) 
print 'p1:', p1 
p2 = p1.copy_point(20) 
print 'p2: Point(%s)' % ', '.join(str(p2[i]) for i in xrange(len(p2))) 
print 'distance p1 <-> p2: %.3f' % p1.distance(p2) 

출력 : namedtuple를 사용하여 당신이 __getitem__()를 구현하지 않아도

p1: Point(x=1, y=2, z=3) 
p2: Point(21, 22, 23) 
distance p1 <-> p2: 34.641 

주 자신도 아니고 __str__() 방법을 쓰지 마십시오. __init__()이 필요한 유일한 이유는 추가 된 클래스 인스턴스 카운터를 증가시킬 필요가 있기 때문입니다. namedtuple에는 기본적으로 없거나 수행하지 않습니다.

+0

흥미로운 정보 고마워. – Olexandr

+0

@AlexPi : 천만에. FWIW, 나는 또한 샘플 출력에서'copy_point()'메서드가하는 일이 ** 실제로 ** 지정된 거리만큼 떨어진 다른 점을 생성한다는 것을 볼 수 있음을 지적하고자한다. 즉, '점 (21,22,23)'은 '점 (1,2,3)'에서 20 단위 떨어져 있지 않습니다. – martineau

+0

예, 알고 있습니다. 테스트 용이었습니다. 더 이상 존재하지 않습니다;) – Olexandr

6

__getitem__ 방법을 쓴다.

은 또한 당신은 튜플로 자신의 내부 스토리지, 스위치 및 속성을 만들 수 X, Y 및 Z : 아마로 클래스를 디자인 할

def __init__(self, x, y, z): 
    self.coords = (x, y, z) 

@property 
def x(self): # sim. for y, z 
    return self.coords[0] 

def __getitem__(self, item): 
    return self.coords[item] 
1

예, 당신이 __getitem__을 정의 할 필요가 있지만, 이는 좌표 및 속성에 대한 색인 및 색인 액세스를 허용합니다.

from collections import namedtuple 

class Point(object): 
    def __init__(self, x, y, z): 
     self._coords = namedtuple('Coords', 'x y z')._make((x, y, z)) 

    @property 
    def coords(self): 
     return self._coords 

    def __getitem__(self, item): 
     return self.coords[item] 

    def copy_point(self, distance): 
     return Point(*(el + distance for el in self.coords)) 

    def __repr__(self): 
     return 'Point: {}'.format(self.coords) 

p = Point(1, 2, 3) 
p.copy_point(20), p.coords[0], p.coords.x 
# (Point: Coords(x=21, y=22, z=23), 1, 1) 
+0

흥미로운 정보 고마워. – Olexandr

관련 문제