这是我试图编写的代码:
class A(object):
def bind_foo(self):
old_foo = self.foo
def new_foo():
old_foo()
#super().foo()
super(self.__class__,self).foo()
self.foo = new_foo
def __init__(self):
print("A __init__")
def foo(self):
print("A foo")
class B(A):
def __init__(self):
print("B __init__")
super().__init__()
def foo(self):
print("B foo")
super().foo()
class C(A):
def __init__(self):
print("C __init__")
super().__init__()
super().bind_foo()
def foo(self):
print("C foo")
b = B()
b.foo()
c = C()
c.foo()
Run Code Online (Sandbox Code Playgroud)
B类和A类是预期的行为,也就是说,当我打电话时b.foo(),它a.foo()也会调用super().C类是试图模仿孩子B和父A行为,但这次我不想明确地super().foo()放在子类中,但我仍然想要父类foo()调用.它按预期工作.
然而,我不太明白的是A.bind_foo,我必须使用super(self.__class__,self).foo()而不是super().foo.super().foo给了一个
"SystemError: super(): no arguments". …Run Code Online (Sandbox Code Playgroud) 我正在使用attrspython 包,结合继承和插槽。我想从派生方法中调用父类的方法。该问题演示如下:
import attr
@attr.s(slots=True)
class Base():
def meth(self):
print("hello")
@attr.s(slots=True)
class Derived(Base):
def meth(self):
super().meth()
print("world")
d = Derived()
d.meth()
Run Code Online (Sandbox Code Playgroud)
我得到:
TypeError: super(type, obj): obj 必须是 type 的实例或子类型
__slots__=()该问题似乎是由 attrs(具有显式工作的未修饰类)、插槽(常规@attr.s修饰类工作)和普通super()调用(工作)的组合触发的super(Derived, self)。
我想了解super()与显式super(Derived, self)版本的行为有何不同,因为文档说它们“做同样的事情”
我在 Python 中有一个对我来说似乎很复杂的问题,它结合了继承、递归和 super() 函数。
首先,我使用的是Python 3,我有一个深度继承的结构。
在第一个父类中,我声明了一个方法,我希望从层次结构中的每个子类调用该方法,但每个子类都有不同的输入。
对我来说,这种结构的使用似乎非常 Pythonic,它确实使我免于大量代码重复。
我的代码的简化示例如下所示:
class ClassA(object):
def __init__(self):
self.attr = 'a'
@classmethod
def _classname(cls):
return cls.__name__
def method1(self):
if self._classname() != 'ClassA': #don't call it for the very first parent class
super().method1()
print(self.attr)
class ClassB(ClassA):
def __init__(self):
self.attr = 'b'
class ClassC(ClassB):
def __init__(self):
self.attr = 'c'
inst1 = ClassC()
inst1.method1()
Run Code Online (Sandbox Code Playgroud)
我希望该代码能够打印
'a'
'b'
'c'
Run Code Online (Sandbox Code Playgroud)
相反,它引发了一个属性错误:
super().method1()
AttributeError: 'super' object has no attribute 'method1'
Run Code Online (Sandbox Code Playgroud)
我知道这是一个复杂的问题,但我试图将其分解。我试图删除递归部分,但我没有得到任何改善。
基于我所做的各种尝试,我相信我非常接近问题的原因,在我看来就像是语法问题或那么简单的事情。
谢谢!!
我在Python 3.4中有这样的函数:
def is_value_valid(the_str):
return len(the_str) != 0
Run Code Online (Sandbox Code Playgroud)
当然还有其他方法来写这个,比如return the_str != "".是否有更多pythonic方式来编写这个表达式?我熟悉truthy/falsy的概念,所以我知道我可以在if条件下快捷方式:
if not the_str:
# do stuff
Run Code Online (Sandbox Code Playgroud)
但是if 期望在它的表达式中有一个布尔结果(这是我作为C++程序员的天真过度简化;我不熟悉这方面的标准).但是,没有任何东西可以强制表达式在return语句中求值为boolean.我试过只返回字符串,只要没有人将返回的值视为字符串,它在boolean context下调用代码就可以了.但是从后置条件的角度来看,我不想返回非布尔类型.
我是猴子修补__eq__类的方法。我发现以下作品:
def eq(obj, other):
if isinstance(other, str):
return obj.name.upper() == other.upper()
else:
return object.__eq__(obj, other)
Run Code Online (Sandbox Code Playgroud)
这不起作用:
def eq(obj, other):
if isinstance(other, str):
return obj.name.upper() == other.upper()
else:
return super().__eq__(other)
Run Code Online (Sandbox Code Playgroud)
这有时可行,但有时会引发错误:
def eq(obj, other):
if isinstance(other, str):
return obj.name.upper() == other.upper()
else:
return super().__eq__(self, other)
Run Code Online (Sandbox Code Playgroud)
错误:
<ipython-input-128-91287536205d> in eq(obj, other)
3 return obj.name.upper() == other.upper()
4 else:
----> 5 return super().__eq__(self, other)
6
7
RuntimeError: super(): __class__ cell not found
Run Code Online (Sandbox Code Playgroud)
您能解释一下这里发生了什么吗?如何正确替换object为super()?
python ×5
super ×3
inheritance ×2
python-3.x ×2
boolean ×1
class ×1
overloading ×1
python-attrs ×1
truthiness ×1