3

У меня есть следующий пример настройки:Python класс наследования Инициализация

class Feet: 
    def __init__ (self, value = 0.0): 
     self.value = value 
     self.units = "f" 

    def feet(self): 
     return self.value 


class Meters: 
    def __init__(self, value = 0.0): 
     self.value = value 
     self.units = "m" 

    def feet(self): 
     # This is probably not an accurate conversion. 
     return self.value * 2.54 * 10 


class Distance (Feet, Meters): 
    def __init__(self, type = Feet()): 
     Feet.__init__(self) 
     Meters.__init__(self) 
     print type.feet() -- Prints 254.0 
     self = type 
     print self.feet() -- Prints 254.0 

dist = Distance(Meters(10.0)) 

print dist.units -- Prints = "m" 
print dist.value -- Prints = 0.0 
print dist.feet() -- Prints = 0.0 

Я не могу понять, почему, когда я инициализировать класс к типу счетчиков класса и присвоить его 10.0, я не держу 10.0. Однако подразделения, похоже, остались верными. Я что-то пропустил о том, как это происходит?

Мое понимание заключается в том, что я создаю «экземпляр» счетчиков и присваиваю его «собственной» переменной Distance. Если значение self не может быть изменено, я мог бы понять, были ли мои единицы «f», но мои единицы «m», поэтому он явно присваивает класс Meters себе, но он не принимает инстанцированные значения, которые я нахожу довольно странными ,

Если честно, я даже не знаю, что я буду делать в этом случае Google, поэтому я извиняюсь, что не сделал много поискового запроса, большинство из того, что я нашел, совсем не применимо к этому типу проблема.

Кроме того, мой план состоял в том, чтобы в основном «отличить» его к тому же типу независимо от того, что вы прошли, например, для ног я вернул бы экземпляр сам по классу футов, а в классе «Метров» я возвращал футы (self.Value * 2.54 * 10), поэтому у меня всегда было бы расстояние в футах.

так для ног ноги становится

def feet(self): 
    return self 

для счетчиков ног становится

def feet(self): 
    return Feet(self.value * 2.54 * 10) 

повторим, есть причина, по которой я могу пройти в 1 из 2 классов как часть инициализации , но он не принимает мои параметры инициализации для этого класса?

Мне действительно непонятно, почему я могу назначить «я» в классе расстояния, а до его возвращения появляется, чтобы иметь правильную инициализацию, но по возвращении он не работает правильно.

+0

Вы переопределяете все методы. Первые два класса имеют те же методы. Вы наследуете от обоих, поэтому методы второго класса переопределяют метод первого класса. – Paco

ответ

5

Дело в том, что вы наследуете от 2-х классов футов и метров. Оба класса имеют одинаковые методы. В вашем методе Distance.__init__(), переопределение методов Feet с методами метровых при этом:

Feet.__init__(self) 
    Meters.__init__(self) 

То, что я сделал бы по-другому:

class Distance(object): 
    def __init__(self, meters=None, feet=None): 
     self.feet = feet 
     self.meters = meters 

Затем вы можете сделать что-то вроде:

distance = Distance(meters=Meters(12)) 
print distance.meters.value 
print distance.meters.type 
# Here do whatever you want with them 

Вы можете передать оба объекта одновременно. И сделайте некоторые другие вещи с двумя объектами, если они оба отличаются от None.

+0

Когда я удаляю оба случая, у меня тогда нет «атрибутных» единиц, так как мне «инициализировать» классы, если это имеет смысл? Я просто попробовал тип .__ init __ (self), но затем, когда я печатаю «type.feet()», он выводится как неподдерживаемый тип операнда для экземпляра * и float, но .value должен быть float, а не экземпляром. – onaclov2000

+0

В этом случае вы не должны наследовать 2 класса, я отредактирую свой ответ с другим – Paco

2

Здесь нет никаких оснований наследовать ни футы, ни метры здесь, не говоря уже обоим. Это классический случай композиции, а не наследование, тем более, что вы передаете класс единиц в качестве параметра. Удалите это подклассом, и в __init__ вы можете сделать self.type = type.

1

Другие ответы охватывают проблемы, которые у вас есть с унаследованием, но не наделили ваш переплет self.

Внутри метода (например, __init__) self - это просто локальное имя, связанное с экземпляром. Вы совершенно свободны переписывать имя, но это просто делает self ссылкой на что-то еще. Это не влияет на экземпляр.

В этом случае, когда __init__ возвращает имя self выходит из области видимости, но оригинальный экземпляр присваивается dist так же, как если бы вы не отскочить имя self.

Обратите внимание, что __init__ является инициализатором, а не конструктором. Python также позволяет вам определить пользовательский конструктор для класса (__new__), и конструктор может изменить возвращаемый объект. Однако вам не нужно использовать его здесь.

0

Эта линия:

self = type 

не делать то, что вы думаете, что он делает. Вы считаете, что это оператор присваивания, в котором объект, на который ссылается self, принимает атрибуты type, a la C++.

У Python нет назначений в том же смысле, что и на других языках.

Что делает эта строка, это привязать локальное имя self к объекту, к которому привязано type. Он абсолютно не действует за пределами Distance.__init__() и практически не влияет на объект, к которому ранее была привязана self.

Смежные вопросы