Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何强制python指向子级甚至父级调用?_Python_Oop - Fatal编程技术网

如何强制python指向子级甚至父级调用?

如何强制python指向子级甚至父级调用?,python,oop,Python,Oop,现在我有 class A: def start(self): return True class B(A): def start(self): return False 现在,如果我想让所有A()调用指向或重定向到B类 比如说 s=A() s.start() 它应该返回False,因为A被B覆盖到返回False 可能吗 好的,编辑 我的案例是在Django视图中,它在第三方包url中被调用,我想覆盖,包调用我的孩子,我覆盖了它,但我通过覆盖url

现在我有

class A:
    def start(self):
       return True

class B(A):
    def start(self):
       return False
现在,如果我想让所有
A()
调用指向或重定向到
B
类 比如说

s=A()
s.start()
它应该返回False,因为
A
B
覆盖到
返回False

可能吗

好的,编辑
我的案例是在Django视图中,它在第三方包url中被调用,我想覆盖,包调用我的孩子,我覆盖了它,但我通过覆盖url本身解决了这个问题,所以我想问它是否可以作为pythonic方式而不是Django方式来完成。

技术上,@BryanOakley的[现已删除]答案是正确的:如果您想使用子类的特性,请实例化子类

也就是说,您仍然可以从子对象访问父对象的方法。假设你有

class A:
    def start(self): return True
    def finish(self): return True


class B:
    def start(self): return False
    def finish(self): return False
如果您希望实例化
A
,但使用
B
start
方法的原因是希望使用
A
finish
方法,那么在子对象上调用父对象的方法总是比反之安全得多:

b = B()
b.start()
A.finish(b)
这是一种非常合理的技术,而且使用非常普遍。如果你谨慎使用它,它本身就没有什么不安全的地方

现在,Python使用duck类型。访问特定方法或属性时,它将尝试直接访问该方法或属性,通常不检查对象的类型。这意味着从技术上来说,我真的不建议这样做,你可以这样做

a = A()
B.start(a)
a.finish()
如果
B
start
方法无法访问存在于子对象中但不存在于父对象中的内容,则可以对此进行处理。但请不要这样做,代码有变化的趋势,你现在“可以侥幸逃脱”的东西通常会在以后咬到你

编辑

听上去,在你编辑之后,你可能在问关于猴子补丁的问题。看起来您实际上想要用在别处定义的替代实现替换现有类中的方法
start
。这通常不是一个好主意:只要有可能,最好提前正确配置。也就是说,你可以这样做:

# Defined externally
class A:
    def start(self): return True

# Defined by you
def start(self): return False

A.start = start

a = A()
a.start()  # False

如果只考虑一个方法,可以直接替换它,如下所示。你不需要一个完整的类定义。您可以使用非常类似的技术在模块级别对类(或其他属性)进行monkey修补。由于所有导入的模块通常指向同一个对象,因此更改在整个代码中都是可见的。猴子在实例上修补方法也是可能的,但不那么简单。

从技术上讲,@BryanOakley的[now deleted]答案是正确的:如果您想使用子类的功能,请实例化子类

也就是说,您仍然可以从子对象访问父对象的方法。假设你有

class A:
    def start(self): return True
    def finish(self): return True


class B:
    def start(self): return False
    def finish(self): return False
如果您希望实例化
A
,但使用
B
start
方法的原因是希望使用
A
finish
方法,那么在子对象上调用父对象的方法总是比反之安全得多:

b = B()
b.start()
A.finish(b)
这是一种非常合理的技术,而且使用非常普遍。如果你谨慎使用它,它本身就没有什么不安全的地方

现在,Python使用duck类型。访问特定方法或属性时,它将尝试直接访问该方法或属性,通常不检查对象的类型。这意味着从技术上来说,我真的不建议这样做,你可以这样做

a = A()
B.start(a)
a.finish()
如果
B
start
方法无法访问存在于子对象中但不存在于父对象中的内容,则可以对此进行处理。但请不要这样做,代码有变化的趋势,你现在“可以侥幸逃脱”的东西通常会在以后咬到你

编辑

听上去,在你编辑之后,你可能在问关于猴子补丁的问题。看起来您实际上想要用在别处定义的替代实现替换现有类中的方法
start
。这通常不是一个好主意:只要有可能,最好提前正确配置。也就是说,你可以这样做:

# Defined externally
class A:
    def start(self): return True

# Defined by you
def start(self): return False

A.start = start

a = A()
a.start()  # False

如果只考虑一个方法,可以直接替换它,如下所示。你不需要一个完整的类定义。您可以使用非常类似的技术在模块级别对类(或其他属性)进行monkey修补。由于所有导入的模块通常指向同一个对象,因此更改在整个代码中都是可见的。猴子在实例上修补方法也是可能的,但不那么简单。

这在技术上是可能的。问题是为什么?你想实现什么?实际上,
A
不是被
B
覆盖的,它是
B
的子类。因此,如果您创建
A
的实例,它完全独立于
B
。您为什么要修改父类的行为?子类化的原因是,您可以更改子类中父类的行为,而不是修改父类本身。换句话说,您是否可以更改
a
,或者您是否试图在无法控制调用代码的情况下修改调用它的修补代码?您是否熟悉monkeypatching,难道这就是你真正想问的?(即:实际上在运行时修改基类,用不同的函数替换它的一个方法)这在技术上是可能的。问题是为什么?你想实现什么?实际上,
A
不是被
B
覆盖的,它是
B
的子类。因此,如果创建
A
的实例,它完全独立于
B