假设我在类中有一个方法,其结构如下:
class TestClass(object):
...
def __init__(self, ...)
...
self.var1 = ...
self.var2 = ...
...
...
def xyz(self, other)
if isinstance(other, TestClass):
...
self.var1 = ...
...
else:
...
self.var2 = ...
...
现在假设我要编写另一个继承自NewTestClass
的类TestClass
(即class NewTestClass(TestClass): ...
)。
方法xyz
的一个问题是它显式检查other
变量是否是TestClass
的实例,它还引用了实例的属性(即{{1} },self.var1
)。
(a)如何重写方法self.var2
,以便在继承(xyz
)后,NewTestClass
语句的行为类似于if
(我不会&#39} ; t必须在if isinstance(other, NewTestClass): ...
)内重写方法xyz
?
(b)同样地,假设我NewTestClass
中有另一个method
引用TestClass
中的staticmethod
,例如:
TestClass
此处,方法@staticmethod
def abc(x):
...
val = ...
...
return val
def mnp(self, ...):
...
x1 = ...
self.var1 = TestClass.abc(x1)
...
使用mnp
的{{1}}(在此示例中为staticmethod
)。如何重写TestClass
,以便在TestClass.abc
继承TestClass.abc
时,它会获得一个方法NewTestClass
,将TestClass
行视为等效{{1} (并且我不必在mnp
内重写方法self.var =
)?
答案 0 :(得分:2)
A)
def xyz(self, other):
if isinstance(other, self.__class__):
...
b)您可以使用self
:
def mnp(self, ...):
....
self.var1 = self.abc(...)
答案 1 :(得分:2)
对于(a)部分,您需要检查other
是否是与self
相同的类的实例:
class TestClass(object):
def xyz(self, other):
if isinstance(other, self.__class__):
...
self.var1 = ...
...
else:
...
self.var2 = ...
...
它通常被认为更多' pythonic'在可能的情况下避免isinstance
这种逻辑。考虑使用Python的鸭子打字。以下示例并不完全符合您的需要,因为您的类中存在这两个属性。但是,如果您为实际代码选择了适当的例外,这种技术将起作用。
class TestClass(object):
def xyz(self, other):
try:
self.var1 = ... # The minimum code required to raise the exception
except AttributeError:
self.var2 = ...
else:
pass # Any other code if the exception is not raised
Python的异常处理是轻量级的,旨在以这种方式使用。如果传递意外(可能尚未考虑)的内容,它会使您的代码更具弹性。
对于(b)部分,在调用静态方法时不需要指定类。它可以在实例(self
)上调用。
class TestClass(object):
@staticmethod
def abc(x):
return x # Do something useful
def mnp(self, x):
self.var1 = self.abc(x)
现在,当您在派生类中声明一个新的静态方法时,它将被正确调用:
class NewTestClass(TestClass):
@staticmethod
def abc(x):
return x * 2 # Do something else useful
a = NewTestClass()
a.mnp(1)
assert a.var1 == 2 # because NewTestClass.abc was called by mnp
答案 2 :(得分:0)
你可以做一些丑陋的反思,让它发挥作用,但这不是正确的事情。如果课程假设自然地相互延伸 - 如果没有,那就去做吧 - 不要。
那就是说,你可以做的一件事就是改变当前的实现,而不是分配一个var来调用另一个函数,并在每个类中实现这个函数来修改正确的变量。
例如,更改:
def xyz(self, other)
if isinstance(other, TestClass):
...
self.var1 = ...
...
else:
...
self.var2 = ...
...
为:
def xyz(self, other)
if isinstance(other, TestClass):
...
self.modifyVar(value)
...
else:
...
self.var2 = ...
...
然后在一个课程中实施:
def modifyVar(self, value):
self.var1 = value
在另一个课程中你会:
def modifyVar(self, value):
self.var2 = value
这个答案涵盖了两种情况(静态和非静态功能)。