Как утверждали другие, у вас нет гарантии относительно порядка, когда вы перебираете свойства объекта. Если вам нужен упорядоченный список нескольких полей, я предложил создать массив объектов.
var myarr = [{somfield1: 'x', somefield2: 'y'},
{somfield1: 'a', somefield2: 'b'},
{somfield1: 'i', somefield2: 'j'}];
Таким образом вы можете использовать регулярный цикл и иметь порядок вставки. Затем вы можете использовать метод сортировки массива, чтобы отсортировать его в новом массиве, если это необходимо.
Это подробно описано с разумным количеством деталей самим Гвидо в его сообщении в блоге Порядок разрешения методов (включая две более ранние попытки).
В вашем примере Third ()
вызовет First .__ init __
. Python ищет каждый атрибут в родительских классах, поскольку они перечислены слева направо. В этом случае мы ищем __ init __
. Итак, если вы определите
class Third(First, Second):
...
Python начнет с рассмотрения First
, и, если First
не имеет атрибута, тогда он будет смотреть на Second
].
Эта ситуация усложняется, когда наследование начинает пересекать пути (например, если Первый
унаследован от Второй
). Прочтите ссылку выше для получения более подробной информации, но, вкратце, Python будет пытаться поддерживать порядок, в котором каждый класс появляется в списке наследования, начиная с самого дочернего класса.
Так, например, если у вас есть:
class First(object):
def __init__(self):
print "first"
class Second(First):
def __init__(self):
print "second"
class Third(First):
def __init__(self):
print "third"
class Fourth(Second, Third):
def __init__(self):
super(Fourth, self).__init__()
print "that's it"
MRO будет [Четвертый, Второй, Третий, Первый].
Между прочим: если Python не может найти согласованный порядок разрешения методов, он вызовет исключение вместо того, чтобы вернуться к поведению, которое может удивить пользователя.
Отредактировано, чтобы добавить пример неоднозначного MRO:
class First(object):
def __init__(self):
print "first"
class Second(First):
def __init__(self):
print "second"
class Third(First, Second):
def __init__(self):
print "third"
Должен Третья
MRO быть [Первый, Второй]
или [Второй, Первый]
]? Нет очевидных ожиданий, и Python выдаст ошибку:
TypeError: Error when calling the metaclass bases
Cannot create a consistent method resolution order (MRO) for bases Second, First
Edit: Я вижу, как несколько человек утверждают, что в приведенных выше примерах отсутствуют вызовы super ()
, поэтому позвольте мне объяснить: Примеры должны показать, как строится ТОиР. Они не предназначены для печати «первая \ nсекунда \ третья» или что-то еще. Вы можете - и, конечно же, должны поэкспериментировать с примером, добавить вызовы super ()
, посмотреть, что происходит, и получить более глубокое понимание модели наследования Python. Но моя цель здесь - упростить и показать, как строится ТОиР. И он построен, как я объяснил:
>>> Fourth.__mro__
(<class '__main__.Fourth'>,
<class '__main__.Second'>, <class '__main__.Third'>,
<class '__main__.First'>,
<type 'object'>)
В python 3.5 + наследование выглядит предсказуемым и очень хорошим для меня. Смотрит на этот код:
class Base(object):
def foo(self):
print(" Base(): entering")
print(" Base(): exiting")
class First(Base):
def foo(self):
print(" First(): entering Will call Second now")
super().foo()
print(" First(): exiting")
class Second(Base):
def foo(self):
print(" Second(): entering")
super().foo()
print(" Second(): exiting")
class Third(First, Second):
def foo(self):
print(" Third(): entering")
super().foo()
print(" Third(): exiting")
class Fourth(Third):
def foo(self):
print("Fourth(): entering")
super().foo()
print("Fourth(): exiting")
Fourth().foo()
print(Fourth.__mro__)
Выводы:
Fourth(): entering
Third(): entering
First(): entering Will call Second now
Second(): entering
Base(): entering
Base(): exiting
Second(): exiting
First(): exiting
Third(): exiting
Fourth(): exiting
(<class '__main__.Fourth'>, <class '__main__.Third'>, <class '__main__.First'>, <class '__main__.Second'>, <class '__main__.Base'>, <class 'object'>)
, Как Вы видите, это называет нечто точно ОДНИМ временем для каждой наследованной цепочки в том же порядке, как это было наследовано. Можно получить тот порядок путем вызова . mro:
Четвертый-> Треть-> Сначала-> Второй-> Основа-> объект
Это известно как проблема алмаза , на странице есть запись на Python, но короче говоря, Python будет вызывать методы суперкласса слева направо.