相关疑难解决方法(0)

为什么Python 3.x的超级()魔术?

在Python 3.x中,super()可以不带参数调用:

class A(object):
    def x(self):
         print("Hey now")

class B(A):
    def x(self):
        super().x()
Run Code Online (Sandbox Code Playgroud)
>>> B().x()
Hey now
Run Code Online (Sandbox Code Playgroud)

为了使这项工作,一些编译时间魔法进行,其中的一个后果是,下面的代码(重新绑定supersuper_)失败:

super_ = super

class A(object):
    def x(self):
        print("No flipping")

class B(A):
    def x(self):
        super_().x()
Run Code Online (Sandbox Code Playgroud)
>>> B().x()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in x
RuntimeError: super(): __class__ cell not found
Run Code Online (Sandbox Code Playgroud)

super()如果没有编译器的帮助,为什么无法在运行时解析超类?是否存在这种行为或其潜在原因可能会让一个不知情的程序员陷入困境的实际情况?

...并且,作为一个附带问题:在Python中是否有任何其他函数,方法等示例可以通过将它们重新绑定到不同的名称来打破?

python super python-3.x

153
推荐指数
1
解决办法
4万
查看次数

如何避免使用super()进行无限递归?

我有这样的代码:

class A(object):
    def __init__(self):
          self.a = 1

class B(A):
    def __init__(self):
        self.b = 2
        super(self.__class__, self).__init__()

class C(B):
    def __init__(self):
        self.c = 3
        super(self.__class__, self).__init__()
Run Code Online (Sandbox Code Playgroud)

实例化B按预期工作但实例化C无限递归并导致堆栈溢出.我怎么解决这个问题?

python oop multiple-inheritance super

28
推荐指数
1
解决办法
4815
查看次数

如何子类化OrderedDict?

对Python进行子类化dict按预期工作:

>>> class DictSub(dict):
...     def __init__(self):
...         self[1] = 10
...         
>>> DictSub()
{1: 10}
Run Code Online (Sandbox Code Playgroud)

但是,用a做同样的事情是collections.OrderedDict行不通的:

>>> import collections
>>> class OrdDictSub(collections.OrderedDict):
...     def __init__(self):
...         self[1] = 10
...         
>>> OrdDictSub()
(…)
AttributeError: 'OrdDictSub' object has no attribute '_OrderedDict__root'
Run Code Online (Sandbox Code Playgroud)

因此,OrderedDict实现使用私有__root属性,这可以防止子类OrdDictSub的行为类似于DictSub子类.为什么?如何从OrderedDict继承?

python inheritance subclass ordereddictionary

28
推荐指数
1
解决办法
5285
查看次数

理解@property装饰器和继承

这里是 Python 3,以防万一它很重要。

我试图正确理解如何在@property使用时实现继承,并且我已经搜索了 StackOverflow 并阅读了 20 个类似的问题,但无济于事,因为他们试图解决的问题略有不同。这是我用于测试的代码:

class Example:
    def __init__(self):
        self.__data = None

    @property
    def data(self):
        return self.__data

    @data.setter
    def data(self, data):
        self.__data = data


class Example2(Example):
    def __init__(self):
        super().__init__()

    @property
    def data(self):
        return super().data  # Works!

    @data.setter
    def data(self, data):
        data = '2' + data
        #Example.data = data   # Works, but I want to avoid using the parent name explicitly
        #super().data = data  # Raises AttributeError: 'super' object has no attribute 'data'
        #super().data.fset(self, data) # …
Run Code Online (Sandbox Code Playgroud)

python inheritance super python-3.x

5
推荐指数
1
解决办法
4433
查看次数

super().method()与super(self .__ class __,self).method()之间的区别

这是我试图编写的代码:

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)

python inheritance class

4
推荐指数
1
解决办法
6588
查看次数

Django模型:在不推荐使用commit_manually时管理事务

我正在运行Django 1.4.11.我save()以类似于以下代码的方式覆盖Django模型的方法:

from django.db import models
from django.db import transaction

class MyModel(models.Model):
    # model definition

    @transaction.commit_manually
    def save(self, *args, **kwargs):
        try:
            super(self.__class__, self).save(*args, **kwargs)
            foo() # do_other_things
        except:
            transaction.rollback()
            raise
        else:
            transaction.commit()
Run Code Online (Sandbox Code Playgroud)

当我运行我的代码时,有时我会在Apache日志中阅读此消息:

RemovedInDjango18Warning:commit_manually已弃用,支持set_autocommit.

如何使用set_autocommit实现相同的逻辑?

python django overriding django-models

4
推荐指数
1
解决办法
3973
查看次数