2012-09-01 3 views
0

파이썬 이미징 라이브러리의 Image 클래스에 새로운 메소드를 추가하려고합니다. DilateImage라는 새로운 클래스를 만들고 싶습니다.이 클래스는 원본 Image 클래스와 똑같은 역할을하지만, 클래스 인스턴스가 실행될 때 클래스 인스턴스를 수정하는 dilate() 함수도 포함됩니다.파이썬에서 (네이티브) 클래스 확장하기

import Image 

def DilateImage(Image): 
    def dilate(self): 
     imnew = self.copy() 
     sourcepix = imnew.load() 
     destpix = self.load() 

     for y in range(self.size[1]): 
     for x in range(self.size[0]): 
      brightest = 255 
      for dy in range(-1,2): 
       for dx in range(-1,2): 
        try: 
        brightest = min(sourcepix[x+dx,y+dy], brightest) 
        except IndexError: 
        pass 
      destpix[x, y] = brightest 

내가 기본 클래스 '를 사용하는 인스턴스를 만들려면이 새로운 클래스 유형을 사용하려고 "열기"기능이 실패 :

>>> test = DilateImage.open("test.jpg") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'function' object has no attribute 'open' 
여기 내 예제 코드 (즉, 작동하지 않는)입니다

답변

3

코드에 두 가지 문제점이 있습니다. 그 중 하나가 이미 지적되었으므로 클래스를 정의 할 때 def 키워드는 함수 또는 메소드를 정의하므로 class 키워드를 사용해야합니다.

두 번째 문제는 코드 모듈에 참조 할에 Image 있도록 전화

import Image 

에서, Image 네임 스페이스에 모듈라는 이미지를 가져올 것입니다. 그것은 객체 또는 클래스가 아니므로

class MyImage(Image) 

는 실패합니다 모듈에서 새로운 클래스를 파생하려고 시도합니다.

Image 모듈에는 Image이라는 클래스가 있습니다. 모듈을 Image 네임 스페이스로 가져온 후에이 클래스를 Image.Image이라고합니다.

import Image as Img 

class MyImage(Img.Image) 

는 모두의 문제입니다 :

import Image 

class MyImage(Image.Image) 

당신은 또한 다른 네임 스페이스로 이미지 모듈을 가져올 수있는이 덜 혼란을 만들려면 :이 클래스를 확장하려면, 예를 들어이를 위해 할 수있는 PIL은 Image 클래스에 이러한 종류의 확장을 허용하도록 설계되지 않은 것처럼 보입니다. 이 모듈은 함수을 Image로 취하고 인수로 Image 인스턴스를 반환합니다. 실제 Image 클래스에는 몇 가지 메소드 만 있습니다. 따라서 Image 클래스를 새로운 메서드로 확장하는 대신 Image 클래스 인스턴스를 생성하고 Image 인스턴스를 새로 만드는 함수를 작성하는 것이 좋습니다. 예를 들면 다음과 같습니다.

import Image 

def DilateImage(source): 
     dest = source.copy() 
     sourcepix = source.load() 
     destpix = dest.load() 

     for y in range(source.size[1]): 
     for x in range(source.size[0]): 
      darkest = 255 
      for dy in range(-1,2): 
       for dx in range(-1,2): 
        try: 
        darkest = min(sourcepix[x+dx,y+dy], darkest) 
        except IndexError: 
        pass 
      destpix[x, y] = darkest 

     return dest 


im1 = Image.open("test.jpg") 

img2 = DilateImage(im1) 

img2.show() 
+0

응답 해 주셔서 감사합니다. 경. – runeks

9

사용

class DilateImage(Image) 

하지

def DilateImage(Image) 
+0

감사합니다. 이제 "class"라인에서 다음과 같은 오류가 발생합니다 :'Traceback (가장 최근 호출 마지막) :''File "piltest.py", 3 행, ''클래스 DilateImage (Image) :' 'TypeError : 메타 클래스베이스 모듈을 호출 할 때 오류가 발생했습니다.__init __()은 최대 2 개의 인수 (3이 주어진)' – runeks

+0

을 가져옵니다. 여기에서 "이미지"는 클래스가 아니며 가져 오는 모듈의 이름입니다. 이 모듈에는 "Image"라는 클래스가 있습니다. 'class DilateImage (Image.Image) '라고 말하면 클래스를 확장하려고 할 수 있지만'open()'함수는'Image.Image' 클래스의 메소드가 아니라'Image' 클래스의 함수입니다. 모듈을 호출하고,'Image.Image' 인스턴스를 리턴합니다. 필자가 말할 수있는 한, PIL은 실제로 그러한 객체 지향 방식으로 확장되도록 설계되지 않았습니다. –

+0

@JanHlavacek 답변으로 게시해야합니다. –

1

class 키워드를 사용해야 할 때 을 (def을 사용하여) 함수로 정의합니다. 따라서 AttributeError은 기능에 open 속성이 없기 때문에 발생합니다.

+0

고마워, 내가 어떻게 그걸 놓쳤는지 모르겠다. 내가 다른 대답에 대한 언급에서 언급했듯이, 이제 나는 다른 해석을하는 법을 알지 못한다.'Traceback (가장 최근 호출 마지막) :' 'File "piltest.py", 3 행, ( ) TypeError : 메타 클래스베이스' '모듈을 호출 할 때 오류가 발생했습니다 .____ __()은 최대 2 개의 인수 (3 개)를 사용합니다. – runeks

관련 문제