2012-09-01 69 views
0

我试图从Python Imaging Library中为Image类添加一个新方法。我想有一个名为DilateImage的新类,它的行为与原始的Image类完全一样,除了它还包含一个dilate()函数,该函数在其上执行时修改类实例。这里是我的示例代码(不工作):在Python中扩展(native)类

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

您的代码有两个问题。其中之一已被指出,定义一个类时,您需要使用关键字class,因为def关键字定义了一个函数或方法。

的第二个问题是呼叫

import Image 

将导入模块称为图像到Image命名空间,让Image在你的代码会引用到模块。这不是一个对象或类,所以

class MyImage(Image) 

将尝试从模块,这将无法获得一个新类。

Image模块包含一个名为Image的类。在将模块导入Image命名空间后,您将该类称为Image.Image

import Image 

class MyImage(Image.Image) 

为了使这个容易混淆,你也可以将图像导入模块插入不同的命名空间:

import Image as Img 

class MyImage(Img.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”-line:“Traceback(最近调用最后一次):''File”piltest.py“,第3行,在'class DilateImage(Image):' TypeError:调用元类base模块时出错。__init __()至多需要2个参数(给出3个)' – runeks

+0

这里,“Image”不是一个类,它是你正在导入的模块的名称。该模块包含一个名为“Image”的类。您可以尝试通过说'class DilateImage(Image.Image)'来扩展该类,但是,open()函数不是Image.Image类的一个方法,而只是Image中的一个函数。模块,并将返回一个'Image.Image'的实例。据我所知,PIL并不是真的被设计成以这种OO方式扩展。 – 2012-09-12 01:51:17

+0

@JanHlavacek你应该发布这个答案。 –

1

当您应该使用class关键字时,您将DilateImage定义为函数(使用def)。因此,AttributeError,因为函数没有open属性。

+0

谢谢,我不知道我是如何错过的。正如我在对另一个答案的评论中提到的,现在我又遇到另一个错误,我不知道如何解释:“Traceback(最近调用最后一个):' '文件”piltest.py“,第3行,在调用元类base时出错' 'module .__ init __()最多需要2个参数(给出3个)' – runeks