在python中访问超级(父)类变量

时间:2018-11-07 13:01:15

标签: python python-3.x class

我是python的新手。我试图使用super()方法访问子类中的父类变量,但会引发错误“无参数”。使用类名访问类变量是可行的,但我想知道是否可以使用super()方法访问它们。

class Parent(object):
        __props__ = (
            ('a', str, 'a var'),
            ('b', int, 'b var')
        )

        def __init__(self):
            self.test = 'foo'

class Child(Parent):
    __props__ = super().__props__ + (
        ('c', str, 'foo'),
    ) # Parent.__props__


    def __init__(self):
        super().__init__()

错误:

    __props__ = super().__props__ + (
RuntimeError: super(): no arguments

5 个答案:

答案 0 :(得分:1)

super可帮助您在拥有父类的实例时获取它。据我所知,没有一个简单的方法就可以在类级别上没有实例,就像您要尝试的那样。我想到的唯一方法是显式引用父类:

class Child(Parent):
    __props__ = Parent.__props__ + ...

为进一步澄清,有两个基本问题:

  • super()super(Child, self)或更普遍的super(type(self), self)的语法糖。由于没有self在您使用它的地方,所以没有任何意义。
  • 在调用Child时,甚至不存在类super()。它仍在定义过程中,因此甚至没有super(Child, self)(继续尝试,我可以等待),这将是无效的语法,因为Child还不是问题。 / li>

因此,您需要显式地引用父类,如我上面显示的那样。

答案 1 :(得分:1)

您可以定义<!doctype html> <html> <head> <meta content="width=device-width, initial-scale=1" name="viewport"> <meta charset="UTF-8"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> <!-- Include the AngularJS library --> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.2/angular.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-sanitize/1.7.5/angular-sanitize.js"></script> <script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> <!--<script src="js/respond.js"></script>--> </head> <body ng-app="app"> <div class="container" ng-controller="MainController"> <h1>{{ mainTitle }}</h1> <h2>{{ headLine }}</h2> <div class="flex-parent"> <div class="flex-child-edge"></div> <div class="flex-child-text"> <h3>{{ teamSection }}</h3> </div> <div class="flex-child-edge"></div> </div> <div class="main" ng-repeat="team in teams"> <!-- PERSON 1 --> <div class="col-xs-6 col-md-3 col-sm-4 person"> <img ng-src="{{ team.mainImage }}" class="img-responsive center-block fade" alt="{{team.alt}}" data-toggle="modal" data-target="#person{{$index}}" /> <div class="red-more-mobile visible-xs" data-toggle="modal" data-target="#person{{$index}}">{{team.mobile}}</div> <div class="name">{{ team.name }}</div> <div class="role">{{ team.role }}</div> </div> <!-- Modal --> <div class="modal " id="person{{$index}}" tabindex="-1" role="dialog"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button> </div> <div class="roundProfile row"> <div class="col-xs-12"> <img ng-src="{{ team.roundImage }}" class="img-responsive img-circle center-block" alt="" /> </div> <div class="name">{{ team.name }}</div> <div class="role">{{ team.role }}</div> <hr> </div> <div class="modal-body" ng-repeat="modal in modals"> <ul class="nav nav-pills"> <li class="active"><a data-toggle="pill" href="#home">{{modal.bio}}</a></li> <li><a data-toggle="pill" href="#menu1">{{modal.experience}}</a></li> <li><a data-toggle="pill" href="#menu2">{{modal.motto}}</a></li> </ul> <div class="tab-content"> <div id="home" class="tab-pane in active"> <p ng-bind-html="team.bio"></p> </div> <div id="menu1" class="tab-pane "> <p>{{ team.experience }}</p> </div> <div id="menu2" class="tab-pane "> <p>{{ team.motto }}<span class="author">{{ team.author }}</span></p> </div> </div> </div> </div> </div> </div> </div> </div> <!-- Modules --> <script src="js/app.js"></script> <!-- Controllers --> <script src="js/controllers/MainController.js"></script> </body> </html>类的__init_subclass__方法来初始化Parent。每次创建Child.__props__的子类时都会调用此方法,我们可以使用它来修改该类继承的Parent,并在类定义中传递一个可选的__props__参数。

__props__

答案 2 :(得分:1)

参加聚会有点晚,但这是metaclasses的工作:

class Parent(object):
    __props__ = (
        ('a', str, 'a var'),
        ('b', int, 'b var')
    )

    def __init__(self):
        self.test = 'foo'

class AddPropsMeta(type):
    def __init__(cls, name, bases, attrs):
        cls.__props__ = sum((base.__props__ for base in bases), ()) + cls.__props__
        super().__init__(name, bases, attrs)

class Child(Parent, metaclass=AddPropsMeta):
    __props__ = (
        ('c', str, 'foo'),
    )
>>> Child.__props__
(('a', str, 'a var'), ('b', int, 'b var'), ('c', str, 'foo'))

答案 3 :(得分:0)

您可以使用__new__方法来更改父类的属性。

class Parent(object):
    __props__ = (
        ('a', str, 'a var'),
        ('b', int, 'b var')
    )

    def __init__(self):
        self.test = 'foo'


class Child(Parent):

    def __new__(cls, *args, **kwargs):
        parent = super(Child, cls)
        cls.__props__ = parent.__props__ + (('c', str, 'foo'),)
        return super(Child, cls).__new__(cls, *args, **kwargs)

p = Parent
print(p.__props__)
c = Child()
print(c.__props__)

输出:

(('a', <type 'str'>, 'a var'), ('b', <type 'int'>, 'b var'))
(('a', <type 'str'>, 'a var'), ('b', <type 'int'>, 'b var'), ('c', <type 'str'>, 'foo'))

与此同时要注意:

print(p.__props__)
c = Child
print(c.__props__)
c = Child()
print(c.__props__)
c = Child
print(c.__props__)

输出:

(('a', <type 'str'>, 'a var'), ('b', <type 'int'>, 'b var'))
(('a', <type 'str'>, 'a var'), ('b', <type 'int'>, 'b var'))
(('a', <type 'str'>, 'a var'), ('b', <type 'int'>, 'b var'), ('c', <type 'str'>, 'foo'))
(('a', <type 'str'>, 'a var'), ('b', <type 'int'>, 'b var'), ('c', <type 'str'>, 'foo'))

__props__仅在您的Child类的第一个实例化之后才会更改。

答案 4 :(得分:0)

您的错误是您编写的超级仅使用父类名称。

class Parent:
        __props__ = (
            ('a', str, 'a var'),
            ('b', int, 'b var')
        )

    def __init__(self):
        self.test = 'foo'


class Child(Parent):
    __props__ = Parent.__props__ + (
        ('c', str, 'foo'),
    ) # Parent.__props__


    def __init__(self):
        Parent.__init__()

希望这很有用。谢谢。