alf*_*_80 -1 python properties abc
我编写了一个模拟abc模块和模块使用的代码properties.但是,似乎我无法访问width和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()
Run Code Online (Sandbox Code Playgroud)
我获得的错误消息是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()
Run Code Online (Sandbox Code Playgroud)
Ned*_*der 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()
Run Code Online (Sandbox Code Playgroud)
"固定"(但完全是unpythonic)代码:
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()
Run Code Online (Sandbox Code Playgroud)
现在是严肃的部分:Python不是Java.你不会对普通属性的访问,因为Python作为计算的属性相当不错的支持,需要getter/setter方法(该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()
Run Code Online (Sandbox Code Playgroud)
对于记录,Python没有"私有"/"公共"关键字 - 只有以前导下划线开头的名称是"实现内容",并且不应该被客户端代码访问.请注意,"不应该"仅表示它的含义:没有什么可以阻止您访问它们,但是如果有任何中断,现在或在下一个版本中都不要抱怨.一种"保修无效,如果未密封".
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
Run Code Online (Sandbox Code Playgroud)
另外(最后):Python没有"隐含此"(或"隐式自我").您必须self.attr在方法中使用才能访问任何属性.
| 归档时间: |
|
| 查看次数: |
1252 次 |
| 最近记录: |