Доступ к экземплярам родительского объекта Python - PullRequest
2 голосов
/ 26 июля 2010

В настоящее время я пытаюсь написать многофайловую игру Python (2.6.5) с использованием PyGame. Проблема заключается в том, что один из файлов, «pyconsole.py», должен иметь возможность вызывать методы для экземпляров других объектов, импортируемых из основного файла «main.py». Проблема в том, что у меня есть список в главном файле для хранения экземпляров всех игровых объектов (корабля игрока, вражеских кораблей, станций и т. Д.), Но я не могу вызывать методы из этого списка в «pyconsole.py», несмотря на то, что я делаю from pyconsole import * в «main.py» перед началом основного цикла. Разве это просто невозможно, и я должен вместо этого использовать M4, чтобы объединить каждый файл в один файл, а затем скомпилировать и протестировать / распространить его?

Пример:

bash$ cat test.py
#!/usr/bin/python

import math, distancefrom00
foo = 5

class BarClass:
    def __init__(self):
        self.baz = 10
    def get(self):
        print "The BAZ is ", self.baz
    def switch(self)
        self.baz = 15
        self.get()

bar = BarClass()

def main():
    bar.switch()
    print distancefrom00.calculate([2, 4])

if __name__ == '__main__': main()

bash$ cat distancefrom00.py
#!/usr/bin/python

import math
import test

def calculate(otherpoint):
    return str(math.hypot(otherpoint[0], otherpoint[1]))+" (foo = "+str(test.foo)+"; "+test.bar.get()+")"

bash$ python test.py
The BAZ is  15
The BAZ is  10
Traceback (most recent call last):
  File "test.py", line 24, in <module>
    if __name__ == '__main__': main()
  File "test.py", line 22, in main
    print distancefrom00.calculate([2, 4])
  File "/home/archie/Development/Python/Import Test/distancefrom00.py", line 8, in calculate
    return str(math.hypot(otherpoint[0], otherpoint[1]))+" (foo = "+str(test.foo)+"; "+test.bar.get()+")"
TypeError: cannot concatenate 'str' and 'NoneType' objects

Если мое несколько ограниченное понимание имен, классов и всего этого в Python здесь верно, NoneType означает, что имя test.bar.get() - и, следовательно, test.bar - ни к чему не присвоено.

Ответы [ 4 ]

2 голосов
/ 26 июля 2010

Проблема в том, что один из файлов, "pyconsole.py", должен иметь возможность вызывать методы на экземплярах других объекты, импортированные первичным файлом, "Main.py".

Звучит так, будто зависимости неверны. Обычно ничто не должно вызывать «назад» до основного файла. Этот main.py должен быть связующим звеном, которое объединяет все остальное, и ничто не должно зависеть от этого. Технически зависимости должны сформировать направленный ациклический граф . Как только вы найдете цикл в графе зависимостей, переместите общие аспекты в новый файл, чтобы разорвать цикл.

Итак, переместите вещи из «main.py», которые используются «pyconsole.py», в новый файл. Затем пусть main.py и pyconsole.py импортируют этот новый файл.

1 голос
/ 26 июля 2010

Обратите внимание, что помимо других ответов, когда вы запускаете test.py как скрипт, это модуль __main__.При импорте test.py из distancefrom00.py создается новый модуль test.bar в основном скрипте и test.bar, доступные из distancefrom00.py, совершенно не связаны.Это даже не один и тот же класс: один - __main__.BarClass, а другой - test.BarClass.

Вот почему вы получаете два выхода 15, за которыми следует 10: основной сценарийбыл вызван метод switch, но тестовый модуль bar не был переключен.

Циркулярный импорт в сторону, импорт основного сценария в другой модуль имеет собственный уровень опасности.

0 голосов
/ 26 июля 2010

Проблема с представленным кодом заключается в том, что метод get класса BarClass возвращает значение None, поскольку тело метода содержит только оператор print. Следовательно, в distancefrom00.py результат функции calculate равен:

str + str + str + str + None + str

Следовательно, TypeError: cannot concatenate a 'str' and 'NoneType' objects

Вы можете решить эту проблему, возвращая строку из вызова get. Например,

def get(self):
    return "The BAZ is %s" % self.baz

Также обратите внимание, что у вас есть циклический импорт в ваших двух файлах. test.py импортирует distancefrom00.py и distancefrom00.py импортирует test.py. Как говорит Килотан, циклические зависимости плохие

0 голосов
/ 26 июля 2010

Вы создаете экземпляр объекта в pyconsole в main.py?Если у вас есть класс с именем PyConsole в pyconsole, передайте его методу __init__ параметр, который принимает список игровых объектов.Таким образом, ваш pyConsole объект будет иметь ссылку на объекты.

Надеюсь, это поможет.Похоже, вы просто неправильно поняли, как Python работает с импортированными модулями.

...