0

PythonImagingLibraryからImageクラスに新しいメソッドを追加しようとしています。元のImageクラスとまったく同じように機能するDilateImageという新しいクラスが必要ですが、クラスインスタンスが実行されたときにクラスインスタンスを変更する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

4 に答える 4

9

使用する

class DilateImage(Image)

いいえ

def DilateImage(Image)
于 2012-09-01T19:59:36.437 に答える
3

コードには2つの問題があります。そのうちの1つはすでに指摘されていますが、キーワードは関数またはメソッドを定義するため、クラスを定義するときはclassキーワードを使用する必要があります。def

2番目の問題は、

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()
于 2012-09-12T17:25:58.980 に答える
1

キーワードを使用する必要があるときに、DilateImage(を使用して)関数として定義しています。したがって、関数には属性がないため、 。defclassAttributeErroropen

于 2012-09-01T20:00:47.193 に答える
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):
        ...

これが推奨されるかどうかはわかりませんが、それができるのはすばらしいことです。

于 2020-09-11T23:38:14.563 に答える