在Python中扩展(本机)类

时间:2012-09-01 19:57:36

标签: python class python-imaging-library extend

我正在尝试从Python Imaging Library向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

当我尝试使用这个新的类类型来创建一个使用基类“open”函数的实例时,它失败了:

>>> test = DilateImage.open("test.jpg")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'function' object has no attribute 'open'

4 个答案:

答案 0 :(得分:9)

使用

class DilateImage(Image)

def DilateImage(Image)

答案 1 :(得分:3)

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

第二个问题是电话

import Image

会将名为Image的模块导入Image命名空间,以便代码中的Image引用该模块。它不是一个对象或类,所以

class MyImage(Image)

将尝试从模块派生新类,但这将失败。

Image模块包含一个名为Image的类。将模块导入Image命名空间后,您将此类称为Image.Image。要扩展此类,您可以这样做:

import Image

class MyImage(Image.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()

答案 2 :(得分:1)

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

答案 3 :(得分:0)

我不知道这是否是最近的更改,但是与以前的注释一样,您实际上可以修改/添加到现有的类中。例如:

class list(list):
    #Create an Empty List
    def empty(N:int):
        """Create an N-Long Empty List"""
        return [None]*int(N)

这不会更改'list'类的现有功能,但是会添加一个执行此操作的方法:

>>> list.empty(5)
[None, None, None, None, None]

您也可以对其他类执行此操作,因此可以提供示例代码来更直接地回答您的问题:

#Import Libraries
import Image

#Add Methods to Image
class Image(Image):
    def dilate(*args, **kwargs):
        ...

我不确定是否建议使用其中任何一种,但是您可以这样做很酷!