2013-11-30 4 views
0

Я работаю с python в данный момент и задаюсь вопросом о чем-то. Я не слишком хорош в программировании объектов, поскольку я всегда кодировал императивные языки (в основном, C).Управление классами в python

Так что я спрашиваю себя.

Скажем, у меня есть экземпляр class_1 называемых c1, заявил так:

c1 = class_1(bla bla bla...) 

Say c1 имеет чёрта много объявлений переменных внутри, как

self.x = ... 
self.y = ... 
self.z = ... 
#etc etc 

Теперь у меня есть экземпляр типа class_2, называемый c2. Скажем, c2 объявляется ВНУТРИ функции c1 в инициализации(), как то

c2 = class_2(bla bla bla...) 

Теперь, я удивляюсь, как я мог ... Acces объекты c1 c2 изнутри?

Некоторые могут сказать, что я мог бы наследовать class_2 от класса_1. Это не совсем то, что я хочу на самом деле. Причина в том, что class_1 должен логически включать объекты, которые имеют тип class_2, но class_2 должен обращаться к переменным из класса_1! Если бы я сделал class_2 наследованием от class_1, мне всегда приходилось ... объявлять объекты class_2 во внешнем (для классов) коде. Я хочу работать во внешнем коде с объектами class_1. Как я могу это разумно сделать? Начало ночного кошмара ...

Спасибо!

EDITED:

Контекст, в котором я использую его ... Я, как задание, написать небольшое пространство видеоигру. Я должен вычислить траектории в пространстве. У меня также есть карта. Некоторые параметры, такие как ускорение, скорость вращения и т. Д. Являются специфическими для «карты»: т. Е. Мы проектируем карту с препятствиями и все, но в зависимости от карты какая-то физическая константа меняется. У меня также есть класс «physcis» для обработки различных вычислений, связанных с траекторией, позиционированием и т. Д. И т. Д. Поэтому я просто хочу иметь возможность использовать множество многих экземпляров разных объектов, которые содержатся в «карте», класса, так что я могу использовать эти переменные внутри класса физики! Это законно? Спасибо!

+1

Самый простой способ передать 'self' из' __init__' в качестве аргумента 'class_2'. Кроме того, ваша терминология кажется немного выключенной. Если 'class_1' - ваш класс,' c1' не является классом, это экземпляр. – BrenBarn

+0

'c1' и' c2' выглядят как экземпляры здесь, а не классы. – user2357112

+0

Да, извините, c2 и c1 являются экземплярами их уважающих типов class_2 и class_1, извинения – Yannick

ответ

2

Из того, что я могу собрать из вашего вопроса, каждый класс_2 связан с определенным классом_1. Я назову этот класс_1 родительским объектом.

Вы хотите быть инстанцировании class_2 изнутри родителя, так что-то вроде

class Class_1(object): 
    def __init__(self): 
     self.x = 1 # Your instance variables here 
     self.y = 2 
     self.class_2_instance = Class_2() 

class Class_2(object): 
    def __init__(self): 
     pass 

является то, что вы хотите. Но вам нужно получить доступ к материалам от родителя внутри класса_2, правильно?

Просто передайте родителя в class_2:

class Class_1(object): 
    def __init__(self): 
     self.x = 1 # Your instance variables here 
     self.y = 2 
     self.class_2_instance = Class_2(self) 

class Class_2(object): 
    def __init__(self, class_1_instance): 
     self.class_1_instance = class_1_instance 

И теперь вы можете, внутри class_2, переменных class_1 доступа.

print(self.class_1_instance.x) # prints 1 

редактировать: Вы уточнить кое-что о свой вопрос в комментариях, так как я начал писать этот ответ, так что теперь, когда я знаю, что c1 и c2 есть, я могу показать вам, как вы будете использовать код I» ве здесь написано:

c1 = Class_1() 

c1 теперь будет иметь экземпляр Class_2, содержащийся в нем. Этот экземпляр сможет получить доступ ко всем свойствам c1.

+0

Выбрали свой ответ, так как вы первыми рекомендовали эту стратегию. Большое спасибо! – Yannick

1

Один Хитрость заключается в том, чтобы передать родительский параметр в class2.__init__ и держать его т.д .:

class class2: 
    def __init__(self, parent,): 
     """ Create an instance of class2 saving the parent """ 
     # You might wish to assert that parent is type class1 here 
     self.parent = parent 

Это позволит вам получить доступ к членам class1 внутри class2, как self.parent.member, который, кажется, что вам нужно.

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

Вы можете определить class2 в том же файле, как class1 и class1 может либо наследовать от него или просто члены типа class2, но если вы называете class2 подчеркнутым имя, например, _class2_ затем в соответствии с соглашением, вы делаете их частными в область, в которой они определены, в этом случае файл, в котором они определены, (NB В python private это соглашение - не соблюдается - более соглашение с господом с предупреждением о том, что частные члены могут быть изменены/удалены на любом новая версия).

Обратите внимание, что определение класса не совпадает с созданием экземпляра класса.

Просто, чтобы увидеть, если это может быть сделано, я попробовал:

Python 2.7.5+ (default, Sep 19 2013, 13:48:49) 
[GCC 4.8.1] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> class A: 
...  class B: 
...   def __init__(self): 
...    self.b = 3 
...  def __init__(self): 
...   self.b = B() 
...   self.a = 2 
... 
>>> a = A() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 6, in __init__ 
NameError: global name 'B' is not defined 

Это происходит потому, что остальная часть класса А не существует до тех пор, инициализации не закончен, поэтому класс B должен быть определен внутри INIT до его использования -

>>> class A: 
...  def __init__(self): 
...   class B: 
...    def __init__(self): 
...     self.b = 3 
...   self.a = 2 
...   self.b = B() 
... 
>>> a=A() 
>>> a.b.b 
3 
>>> 
+0

Спасибо за информацию наедине. Я этого не знал! – Yannick

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