我是python和面向对象编程的新手。我有一个关于使用python的OOP的基本问题。假设有一个类初始化了一些实例变量。稍后,我需要添加更多实例变量。我可以在课堂外使用object.attribute = value
来做到这一点。类中的代码不设置属性/变量。
当程序变大时,程序是否会变得难以维护?除了在类中之外,代码中的任何地方都会散布实例变量赋值。使用self.attribute = value
在课堂上进行这些作业是否更好?在哪里可以轻松跟踪这些作业?什么是正确的方法?
答案 0 :(得分:2)
你已经到了一个分叉:左边是“一般”,而在右边你可以看到“特定的”。
通常,是的,您希望对象的成员由定义对象的类确定。这就是拥有一个类的整个点 - 通过将一些代码(方法)和一些数据(实例和类变量)组合在一起来包含和指定类似的行为。
但具体而言,有时候你有一个只需要在某个地方挂起一些数据的函数。它可能与课程无关 - 只是“我之前见过你”或“这里是计算的记忆结果。”
总的来说,是的,您应该努力将所有与课程相关的数据放入您的课程中。但是,如果碰巧出现一些不会发生的具体情况,请不要过于弯曲。
<强>更新强>
经过一些评论后,让我们考虑使用的例子:
按方法使用属性:
如果您有一个或多个使用属性的方法,但一般不为公众所用,那么您可以延迟设置属性直到您使用它:
class Window:
def print_text(self, text):
if self._bg_color is None:
self._bg_color = WHITE
# continue...
此属性不必在您的__init__
方法中,因为您负责确保在使用自己的方法之前设置它。
使用属性作为类的API的一部分。
如果您的属性是该类API的一部分,则无法控制该属性的使用方式。一些愚蠢的用户会做他们想做的任何事情,当它不起作用时,他们会在Stack Overflow上抱怨你的代码。 ; - )
在这种情况下,您有两种选择:(a)您可以确保始终设置它,或者(b)您可以拦截对成员的访问(使用@property
方法)并按需设置它
class Color:
def __init__(self, r, g, b):
self.r = r
self.g = g
self.b = b
# Option (a): Ensure properties are always set:
self.h, self.s, self.v = _compute_hsv(r, g, b)
# Option (b): Intercept property access and compute on demand
@property
def h(self):
if self._h is None:
self._h, self._s, self._v = _compute_hsv(self.r, self.g, self.b)
return self._h
# likewise for s, v