Как Python “супер” делает правильную вещь?

Это работает для загрузки и установки фонового изображения панели содержимого:

jar (или путь сборки) содержит:

 - com
 - img
 ---- bg.png

java содержит:

JFrame f = new JFrame("Testing load resource from jar");
try {
    BufferedImage bg = ImageIO.read(getClass().getResource("/img/bg.png"));
    f.setContentPane(new ImagePanel(bg));
} catch (IOException e) {
    e.printStackTrace();
}

Протестировано и работает как в jar, так и в unjarred (это технический термин).

BTW getClass().getClassLoader().getResourceAsStream("/img/bg.png") - который я пробовал в первую очередь, возвратил мне null InputStream.

51
задан Joseph Garvin 3 March 2009 в 17:00
поделиться

3 ответа

Я обеспечил набор ссылок ниже, которые отвечают на Ваш вопрос более подробно и более точно, чем я могу когда-либо надеяться. Я однако дам ответ на Ваш вопрос в моих собственных словах также, чтобы сэкономить Вам некоторое время. Я помещу его в точки -

  1. супер, встроенная функция, не атрибут.
  2. Каждый тип (класс) в Python имеет __mro__ атрибут, который хранит порядок разрешения метода того конкретного экземпляра.
  3. Каждый вызов к супер имеет форму супер (тип [объект-или-тип]). Давайте предположим, что второй атрибут является объектом в настоящий момент.
  4. В начальной точке вызовов super, объект имеет тип Производного класса (, говорят что DC).
  5. супер ищет методы, которые соответствуют (в Вашем случае __init__) в классах в MRO, после того, как класс определил как первый аргумент (в этом случае классы после DC).
  6. , Когда метод сопоставления найден (говорят в классе BC1 ), это называют.
    (Этот метод должен использовать супер, таким образом, я принимаю, это делает - Видят, что супер Python является остротой, но не может использоваться - ссылка ниже), Что метод тогда вызывает поиск в MRO класса объекта для следующего метода, направо от [1 152] BC1.
  7. повторение промывки Промывки, пока все методы не находят и называют.

Объяснение Вашего примера

 MRO: D,B,C,A,object  
  1. super(D, self).__init__() называют. isinstance (сам, D) => Верный
  2. Поиск следующий метод в MRO в классах направо от D.

    B.__init__ найденный и названный

<час>
  1. B.__init__ вызовы super(B, self).__init__().

    isinstance (сам, B) => Ложь
    isinstance (сам, D) => Верный

  2. Таким образом, MRO является тем же, но поиск продолжается направо от B, т.е. C, A, объект ищется один за другим. Следующее __init__ найденный называют.

  3. И т. д. и т. п.

объяснение супер
http://www.python.org/download/releases/2.2.3/descrintro/#cooperation
Вещи наблюдать за при использовании супер
http://fuhm.net/super-harmful/
Python Алгоритм MRO:
http://www.python.org/download/releases/2.3/mro/
документы super:
http://docs.python.org/library/functions.html
низ этой страницы имеет хороший раздел по супер:
http://docstore.mik.ua/orelly/other/python/0596001886_pythonian-chp-5-sect-2.html

я надеюсь, что это помогает разрешить его.

15
ответ дан Community 7 November 2019 в 20:20
поделиться

Измените свой код на это, и я думаю, что он объяснит вещи (по-видимому super, смотрит на то, где, скажем, B находится в __mro__?):

class A(object):
    def __init__(self):
        print "A init"
        print self.__class__.__mro__

class B(A):
    def __init__(self):
        print "B init"
        print self.__class__.__mro__
        super(B, self).__init__()

class C(A):
    def __init__(self):
        print "C init"
        print self.__class__.__mro__
        super(C, self).__init__()

class D(B, C):
    def __init__(self):
        print "D init"
        print self.__class__.__mro__
        super(D, self).__init__()

x = D()

при выполнении его, Вы будете видеть:

D init
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>)
B init
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>)
C init
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>)
A init
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>)

Также это стоит проверить , Супер Python является остротой, но Вы не можете использовать его .

34
ответ дан Jacob Gabrielson 7 November 2019 в 20:20
поделиться

просто предположение:

self во всех этих четырех методах относятся к тому же объекту, то есть, класса D. таким образом, в B.__init__(), вызов к к super(B,self) знает целую ромбовидную родословную self, и это должно выбрать метод от 'после' B. в этом случае это C класс.

6
ответ дан Javier 7 November 2019 в 20:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: