-1

abcモジュールとの使用をシミュレートするコードを作成しましたpropertieswidthしかし、height変数にアクセスできなかったようです。コードは次のとおりです。

from abc import ABCMeta, abstractmethod

class Polygon:

__metaclass__ = ABCMeta

@abstractmethod
def compute_area(self): pass


def __init__(self):
    self.width = None
    self.height = None

@property
def width_prop(self):
    return self.width

@property
def height_prop(self):
    return self.height

@width_setter.setter
def width_setter(self, width):
    self.width = width

@height_setter.setter
def height_setter(self, height):
    self.height = height



class Triangle(Polygon):
    def compute_area(self):
        return 0.5 * width * height




if __name__ == "__main__":
    tri = Triangle()
    tri.height_setter(20)
    tri.width_setter(30)
    print "Area of the triangle = ", tri.compute_area()

取得したエラーメッセージはですNameError: name 'width_setter' is not defined。私の実装で何が間違っている可能性がありますか?

編集:

from abc import ABCMeta, abstractmethod

class Polygon:

__metaclass__ = ABCMeta

@abstractmethod
def compute_area(self): pass


def __init__(self):
    self.width = None
    self.height = None

@property
def width_prop(self):
    return self.width

@width_prop.setter
def width_setter(self, width):
    self.width = width

@property
def height_prop(self):
    return self.height

@height_prop.setter
def height_setter(self, height):
    self.height = height



class Triangle(Polygon):
    def compute_area(self):
        return 0.5 * self.width * self.height




if __name__ == "__main__":
    tri = Triangle()
    tri.height_prop = 20
    tri.width_prop = 30
    print "Area of the triangle = ", tri.compute_area()
4

3 に答える 3

15

Python を C++ や Java としてではなく、Python として記述します。

class Polygon:
    def compute_area(self):             # if you need this at all...
        raise NotImplementedError()     # what does it do for you?

    def __init__(self):
        self.width = None
        self.height = None

class Triangle(Polygon):
    def compute_area(self):
        return 0.5 * self.width * self.height

if __name__ == "__main__":
    tri = Triangle()
    tri.height = 20
    tri.width = 30
    print "Area of the triangle = ", tri.compute_area()
于 2012-07-07T23:04:14.917 に答える
6

「修正された」(しかし完全に非pythonic)コード:

class Polygon(object):
    __metaclass__ = ABCMeta

    @abstractmethod
    def compute_area(self): 
        pass

    def __init__(self):
        self.width = None
        self.height = None

    @property
    def width_prop(self):
        return self.width

    @width_prop.setter
    def width_prop(self, width):
        self.width = width

    @property
    def height_prop(self):
        return self.height

   @height_prop.setter
   def height_prop(self, height):
    self.height = height


class Triangle(Polygon):
    def compute_area(self):
        return 0.5 * self.width_prop * self.height_prop

if __name__ == "__main__":
    tri = Triangle()
    tri.height_prop = 20
    tri.width_prop = 30
    print "Area of the triangle = ", tri.compute_area()

ここで重要なのは、PythonはJavaではないということです。Pythonは計算された属性の非常に優れたサポートであるため、プレーン属性へのアクセスにゲッター/セッターは必要ありません(正しく使用できなかったタイプproperty、非常に単純な汎用ですが、非常に便利です)。ゲッターとセッターは何も役に立ちません。属性に直接アクセスすると、まったく同じ結果になります(コードが少なくなり、パフォーマンスが向上します)。

class Polygon(whatever):
    __metaclass__ = ABCMeta

    def __init__(self, witdh=None, height=None):
        self.width = width
        self.height = height


    @abstractmethod
    def compute_area(self): 
        pass


class Triangle(Polygon):
    def compute_area(self):
        return 0.5 * self.width * self.height


if __name__ == "__main__":
    tri = Triangle(20, 30)
    print "Area of the triangle = ", tri.compute_area()

ちなみに、Pythonには「private」/「public」キーワードはありません。先頭の下線で始まる名前は「実装のもの」であり、クライアントコードからアクセスするべきではないという規則だけです。「すべきではない」とは、それが意味することだけを意味することに注意してください。現在または次のリリースで何かが壊れても、それらにアクセスすることを妨げるものは何もありません。「開封した場合の保証は無効」の一種。

wrt /適切な使用法またはプロパティ:詳細については説明しませんが(Python実行モデルとオブジェクトモデルの詳細な説明が必要になります)、正しい構文は次のとおりです。

class MyClass(object):

    def __init__(self, prop):
        # this will invoke prop.setter
        self.prop = prop

    # defines a property named "prop"
    # will be accessed just like a plain
    # attribute but will go thru the getter and setter

    @property
    def prop(self):
        # this is the getter
        return self._some_val * 42

    # now add a setter to 'prop':
    @prop.setter
    def prop(self, val):
        self._some_val = val / 42


obj = MyClass(10)
print obj.prop
obj.prop = 5
print obj.prop

また(そして最後に):Pythonには「暗黙のこれ」(または「暗黙の自己」)はありません。属性にアクセスするには、メソッド内で使用する必要があります。self.attr

于 2012-07-07T20:41:52.517 に答える
-5

編集:例のような単純なケースでは、直接変数アクセスを使用します。Ned Batchelder の回答を参照してください。

変数にアクセスするときに追加の機能が必要な場合は、これを使用できます。


http://docs.python.org/library/functions.html#property

from abc import ABCMeta, abstractmethod

class Polygon(object):

    __metaclass__ = ABCMeta

    @abstractmethod
    def compute_area(self): 
        pass


    def __init__(self):
        self._width = None
        self._height = None

    @property
    def width(self):
        getting_variable_value()
        return self._width

    @width.setter
    def width(self, width):
        setting_variable_value()
        self._width = width

    @property
    def height(self):
        getting_variable_value()
        return self._height

    @height.setter
    def height(self, height):
        setting_variable_value()
        self._height = height



class Triangle(Polygon):
    def compute_area(self):
        return 0.5 * self.width * self.height


if __name__ == "__main__":
    tri = Triangle()
    tri.height = 20
    tri.width = 30
    print "Area of the triangle = ", tri.compute_area()
于 2012-07-07T22:03:40.330 に答える