-1

我写了一个代码来模拟abc模块和properties. 但是,似乎我无法访问widthheight变量。代码如下:

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 编写为 Python,而不是 C++ 或 Java:

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

“固定”(但完全不符合标准)代码:

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。您不需要getter/setter 来访问普通属性,因为 Python 作为对计算属性的很好支持(property您未能正确使用的类型是一个非常简单的通用 - 但非常方便 - 实现)。您的 getter 和 setter 没有做任何有用的事情,并且您将获得相同的结果(使用更少的代码和更好的性能)直接访问属性:

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 没有“隐式 this”(或“隐式自我”)。您必须在方法内使用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 回答