Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.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 使用Super设置父类属性_Python_Python 2.7 - Fatal编程技术网

Python 使用Super设置父类属性

Python 使用Super设置父类属性,python,python-2.7,Python,Python 2.7,可以在Python2.7中使用super设置父类属性吗?我希望以下代码能够正常工作,但它不能: class A(object): val_a = 1 class B(A): val_b = 2 def set_a(self, val): super(B,self).__class__.val_a = val b = B() b.set_a(3) 它给出了以下错误: TypeError: can't set attributes of built-

可以在Python2.7中使用super设置父类属性吗?我希望以下代码能够正常工作,但它不能:

class A(object):
    val_a = 1

class B(A):
    val_b = 2

    def set_a(self, val):
        super(B,self).__class__.val_a = val

b = B()

b.set_a(3)
它给出了以下错误:

TypeError: can't set attributes of built-in/extension type 'super'

有正确的方法吗?

根据您的代码,您正在尝试对实例进行更改。然后,函数集_a需要如下所示

class B(A):
    val_b = 2

    def set_a(self, val):
        self.val_a = val
但是如果您需要更改以适用于类级别,则可以使用类方法,而不能使用超级方法

会回来的

五,

五,

直接引用A.val_A。在本例中,val_a是一个静态变量,而不是对象实例的属性

super调用试图获取self instance的对象,因此访问属性superB、self.val_a将失败

class A(object):
    val_a = 1

class B(A):
    val_b = 2

    def set_a(self, val):
        A.val_a = val 

b = B()
b.set_a(3)

print b.val_a
可以在python 2.7中使用super设置静态类属性吗

没有

我希望下面的代码能够工作,但它不能

首先,_类_实际上由super进行特殊大小写,以返回super实例的类,而不是执行通常由super执行的MRO搜索

第二,没有B。超级要绕过的条目,所以即使“类”不是特例,它仍然是B而不是A

第三,如果你想特别提到A类,而不是self的MRO中接下来发生的任何事情,你应该直接提到A类

长话短说:使用A,而不是超级。

请参阅

您不能用super来完成,但您可以搜索子类的基类并以这种方式完成

我的意思是:

class Other(object):
    val_a = 42

class A(Other):
    val_x = 1

    def __str__(self):
        return '{}(val_a={})'.format(self.__class__.__name__, self.val_a)

class B(A):
    val_b = 2

    def set_a(self, val):
        for cls in self.__class__.__mro__[1:]:
            try:
                object.__getattribute__(cls, 'val_a')
            except AttributeError:
                continue
            print('Updating class: {}'.format(cls.__name__))
            cls.val_a = val
            break
        else:
            raise RuntimeError("Can't find a base class with attribute 'val_a'")

b = B()
print(b)  # -> B(val_a=1)                     # B(val_a=42)
print('Other.val_a: {}'.format(Other.val_a))  # Other.val_a: 42
print('A.val_a: {}'.format(A.val_a))          # A.val_a: 42
print('B.val_a: {}'.format(B.val_a))          # B.val_a: 42
print('')
b.set_a(3)                                    # Updating class: Other
print('')
print(b)                                      # B(val_a=3)
print('Other.val_a: {}'.format(Other.val_a))  # Other.val_a: 3
print('A.val_a: {}'.format(A.val_a))          # A.val_a: 3
print('B.val_a: {}'.format(B.val_a))          # B.val_a: 3

你应该去上这门课而不是这门课。super.\uuuuu class\uuuuuuu是super对象的类属性,而super.\uuuuu thisclass\uuuuu是父类的类属性。@Faibbus,我刚刚用\uuuuuu thisclass\uuuuu替换了\uuuuuuuuu class\uuuuuuuuu,效果不错。谢谢我想知道为什么会这样?你为什么要这么做?B继承自A,B的任何实例都可以访问A的属性。你应该在self上设置值。@Faibbus:那是B,不是A。看起来提问者想要A。@Faibbus:是的,但是superA,self。u这个类是编写A的一种非常复杂的方式,没有任何好处。不,对不起。这只会为特定实例设置val_a的值。我想为类A设置它。但是根据您的代码,函数不是类方法,那么它只适用于特定实例。如果你想为类设置变量,set_a需要是一个类方法。这是对你的问题的回答,你可以用super设置静态类属性吗?否则,你可以编辑你的问题,让它更清楚,如果你想让方法为类设置变量。谢谢你的建议。我已经编辑了标题和问题,以使意图更加明确。谢谢你的答复。Faibbus建议将uu this class_uu与super一起使用,实际上似乎确实有效。@p提示:那是B。如果你想分配给B.val_ua,你应该直接分配给B.val_ua,而不是绕着super走弯路。不过,听起来你想分配给A.val_A。你说得对,谢谢——我没听清楚。我想我将只使用A.val_A。通过b设置A的静态属性的值是,这样我就有了一个一致的接口;我什么都可以用b。谢谢你的回答。不幸的是,正如Faibbus的建议一样,这只改变了B类的属性,而不是A类。typeself与使用self没有什么不同。据我所知,1。typeself与使用self没有什么不同,但是看起来更好。。这取决于应用程序。假设您不想弄乱类A名称空间,并且设置了一个在类A中定义的方法。在这种情况下,您可以使用此解决方案。谢谢,这是一个非常好的解决方案。也许比我需要的更复杂。如果你知道只有一个基类,你可以硬编码,无条件地使用self。uuu class_uuu。uuu mro_uu[1]。val\u a=val.hasattrcls,“val\u a”不关心属性是否在类cls中实际定义;它将拾取继承的属性。这个错误在这里不可见,只是因为val_a在MRO的下一个类中定义了。@user2357112:很好,我想我已经在修改后的答案中解决了这个问题。它现在工作得更好了,但不是出于好的原因,也可能不是出于你所想的原因。cls.\uuuuu getattribute\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。碰巧这通常是对象。它不知道如何搜索cls的MRO。如果涉及到另一个uuu getattribute uuuuuu方法,情况就不一样了。使用super的主要原因之一是避免将[base]类名硬编码到子类的代码中。
class A(object):
    val_a = 1


class B(A):
    val_b = 2
    def set_a(self, val):
        type(self).val_a = val


b1 = B()
b1.set_a(3)
b2 = B()
b2.set_a(4)
print type(b1).val_a
print type(b2).val_a
print A.val_a
print B.val_a
class Other(object):
    val_a = 42

class A(Other):
    val_x = 1

    def __str__(self):
        return '{}(val_a={})'.format(self.__class__.__name__, self.val_a)

class B(A):
    val_b = 2

    def set_a(self, val):
        for cls in self.__class__.__mro__[1:]:
            try:
                object.__getattribute__(cls, 'val_a')
            except AttributeError:
                continue
            print('Updating class: {}'.format(cls.__name__))
            cls.val_a = val
            break
        else:
            raise RuntimeError("Can't find a base class with attribute 'val_a'")

b = B()
print(b)  # -> B(val_a=1)                     # B(val_a=42)
print('Other.val_a: {}'.format(Other.val_a))  # Other.val_a: 42
print('A.val_a: {}'.format(A.val_a))          # A.val_a: 42
print('B.val_a: {}'.format(B.val_a))          # B.val_a: 42
print('')
b.set_a(3)                                    # Updating class: Other
print('')
print(b)                                      # B(val_a=3)
print('Other.val_a: {}'.format(Other.val_a))  # Other.val_a: 3
print('A.val_a: {}'.format(A.val_a))          # A.val_a: 3
print('B.val_a: {}'.format(B.val_a))          # B.val_a: 3