А в итоге, фиг меняет. Если память мне не изменяет в бейсике с этим нет проблем. Или может я что-то делаю не так? Сделал модуль для отображеня gui, теперь нужно скрывать или отображать элементы из других модулей. Например из модуля загрузчика, отобразить фон для загрузки. Или прийдется в нем gui создавать. При таком раскладе, пользы от них. ООП -
import module1, module2 x = module1.Start1() module2.Start2(x) print x.a
Code
class Start1(): def __init__(self): self.a = {'s':'eee'}
Code
class Start2(): def __init__(self, object): object.a['s'] = 'fffffdddd'
Питон, в отличае от Васика - объектно-ориентированный язык со ссылочной структурой данных. Вызывая module1.Start1() ты просто создаёшь и инициализируешь ещё один экземпляр объекта Start1. Этого делать не надо. Достаточно один раз создать экземпляр объекта и для работы с ним из других модулей просто передавать ссылку на этот объект.
В качестве шпаргалки-подсказки можно смотреть на скобки - если они есть, значит ты создаёшь новый объект. x = module1.Start1() y = x x и y будут указывать на один и тот же объект. Меняя y, ты будешь менять и x, и наоборот. Аналогия - разные ярлыки на один и тот же файл
НО
x = module1.Start1() y = module1.Start1() x и y - уже разные экземпляры, не зависящие друг от друга.
Сообщение отредактировал ninth - Воскресенье, 09.10.2011, 23:43
Посмотри внимательно def __init__(self, object) self - в данном случаеобязательный аргумент для методов класса. А вот object - как раз ссылка на объект с которым мы уже будем работать - в примере - изменять словарь. Для твоего варианта должно быть так
Code
class Start1(): def __init__(self): self.a = {'s':'eee'}
St1 = Start1()
class Start2(): def __init__(self, obj): obj.a['s'] = 'fffffdddd'
ninth, я понял и знал, что модулю нужно передать ссылку, но выше я пример приводил, рабочий. И твой рабочий. Дело в другом как мне вынести в отдельный файл класс, сохранив в других модулях к нему доступ. Как я понял, импортированный модуль имеет свое пространство имен. И конечно ему каждый раз нужно передавать ссылку на объект (класс, переменная), а это не очень удобно, да и путает программу. Твой вариант можно вынести отдельно, а мой?
Вот еще наглядый и понятный пример. Где все логично.
Code
class Start1(): def __init__(self): self.a = {'s':'eee'}
St1 = Start1()
class Start2(): def __init__(self): St1.a['s'] = 'fffffdddd'
def print_text(self): print St1.a
St2 = Start2()
St2.print_text()
Но после выноса и импортирования такой доступ не возможен, у модуля будет свое имя и пространство. Модули конечно хорошо, но только в том случае, когда нужно создать подпрограмму. Например генератор паролей, передал скажем количество символов и получил набор символов и все. Больше от него ни чего ни нужно. А когда нужно сделать активное использование их между собой, то лучше воздержаться от них, каждому модулю передавать имена, только логику путать. Смотрел Demomaster, хотел выдрать тени, а там сплошные аргументы как паутина. Все-таки выдрал, с кучей странных модулей. Которые и не нужны, а выкинешь, не работает. Полез удалять все ссылки, голову сломал =) ООП -
Категорически не согласен. Использование в корне неправильное. Зачем вообще тогда классы модули, ели ты не можешь их спокойно выдернуть куда тебе надо? При такой работе как пытаешься организовать ты, в конце концов ты получишь рекурсивные ссылки в модулях друг на друга.
Если уж очень хочется работать так, то заноси нужные переменные в __builtin__ и используй где пожелаешь. Но такой код я бы не рекомендовал использовать как учебный, т.к. он прививает неправильный стиль.
Code
import __builtin__
class Start1(): def __init__(self): self.a = {'s':'eee'}
__builtin__.St1 = Start1()
class Start2(): def __init__(self): St1.a['s'] = 'fffffdddd'
Чем дальше в лес, тем темней =) Зачем мне __builtin__? когда все в куче работает и без него. А вот если вынести, то это не поможет. Ведь при импортировании модуля питон матерится на St1, даже не смотря St1 = Start1() что был запущен, или прокатит? И что мне не дает настроенный класс использовать в другом месте? Например Start1() там будут в словаре ноды гуи, и я смогу без проблем управлять их параметрами из других классов. Например из автомата или пистолета?! какие-то проблемы. Я просто к тому что логику дробить на кучу файлов ни к чему. Все равно его не получится использовать где нужно, например гнома, интересно куда его можно запихать? причем без правки, импортировал его и он запустился. ООП -
1. Эм... а ты себе хорошо представляешь объём кода в законченном проекте, чтобы упихать это всё в один файл? Уже после 1000-1500 строк тебе станет неимоверно тяжело ориентироваться в коде. Поверь, я этот этап прошёл ещё на GLScene.
2. Гнома использовать аж влёгкую. Создаём гнома, даём ему 30 случайных точек перемещения и отправляем бродить. Если вместо гнома взять другую модельку, а точки создавать не изначально, а в процессе - получим монстра, который скажем будет охотиться за игроком.
Code
# -*- coding: utf_8 -*- from random import random from panda3d.core import * from modules.character import CharactersList import direct.directbase.DirectStart
base.cTrav = CollisionTraverser() clist = CharactersList() player = clist.newCharacter('res/actors/gnum',{'stand':'res/actors/gnum-stand','walk':'res/actors/gnum-walk'},base.cTrav) for i in xrange(30): player.control('add_wp', ('goto', Vec3(random()*100, random()*100, 0))) taskMgr.add(clist.update,'characters update')
run()
3. Разнеси код по модулям
main.py
Code
from module1 import Start1 from module2 import Start2 import __builtin__ __builtin__.St1 = Start1() St2 = Start2() St2.print_text()
module1.py
Code
class Start1(): def __init__(self): self.a = {'s':'eee'}
module2.py
Code
class Start2(): def __init__(self): St1.a['s'] = 'fffffdddd'
Все ясно, только мне мыслить надо как то по-другому. Видимо мне привился неправильный стиль =). А, вот насчет большого файла как то не задумался. Замечу модуль гнома содержит несколько классов, и чтоб его совершенствовать их нужно дорабатывать, тем самым опять увеличивать размер. Вот с вариантом __builtin__ мне как раз удобно, ну теперь не пойму что плохого в ссылках друг на друга? чем чревато? ООП -
Незапуском программы и чесанием репы из разряда "а как это теперь совмещать если мне надо и то и то"?
Ну такого быть не может, я не говорил что мне нужны ссылки на все переменные в классах. Например глупо в классе автомата иметь ссыль на пистолет. Я говорил о классах которые формируют архитектуру игры, вот они по моему должны быть доступны из этих классов, к примеру для оружия - HUD. Если мы создали экземпляр автомата, то он конфигурирует класс GUI - HUD и другии нужные. Например меняет размер прицела при стрельбе, на основании параметров которые прописанные в файле характеристик и считываются при инициализации класса. А далее распределяются нужным классам логики игры, которые являются только каркасом и без них логика не может существовать. При таком подходе легко написать инструменты для создания карт, персонажей и т.д. просто оперируя файлами параметров.
Данный подход везде и повсюду в играх. Возмем также NeoAxis там все в классах. Любой игровой объект - класс. Стоит заметить логика при таком подходе хочень раздробленна, и это дает гибкость. И по сути вопроса не возникает как что-то совмещать. Не думаю что логика игры рухнет если скажем не создать экземляр класса автомата =) Ведь ссылок на него нет из каркаснах классов, к примеру опять HUD. ООП -
Чот тут всё в кучу намешано: модули, классы, экземпляры класса, члены класса, методы класса, пространства имён. Нужно хотя бы базовые принципы питона понимать, чтобы такими понятиями оперировать.
Сарказм? Сарказм - это хорошо (: Если мой тон показался слишком высокомерным, так это я не со зла, такая уж у меня манера изложения конструктивной критики. Я, честно говоря, не понял какая цель преследуется при разбиении на модули? По идее модули и классы нужны, чтобы "прятать" логику работы конкретного куска кода в, соответственно, модуль или класс. И чтобы тот, кто использует этот модуль или класс использовал только интерфейс, который для него создал разработчик этого модуля или класса. В конкретном примере мне непонятно как классы Start1 и Start2 связаны? Либо Start2 наследуется от Start1, либо Start2 использует экземпляр класса Start1. Остальные способы взаимодействия двух классов представляются мне крайне черезжопными.
Сарказм? Сарказм - это хорошо (: Если мой тон показался слишком высокомерным, так это я не со зла, такая уж у меня манера изложения конструктивной критики.
Ты конструктивно сказал: не понимаете, а говорите. Зачем? Или как понять что-то не говоря об этом? Может и учиться не надо, раз нет понимания? Может при обсуждении темы жесты использовать или сравнивать с банальными понятиями.
Ладно: Как мне написанные буквы изобразить в одном месте и в другом, без появления черного прямоугольника с какими-то буквами, что тужно сделать? Мне так-же интересно знать как буквы запихать в другие буквы?
Имена Об именах (идентификаторах) говорилось уже не раз, тем не менее, необходимо сказать несколько слов об их применении в языке Python. Имя может начинаться с латинской буквы (любого регистра) или подчеркивания, а дальше допустимо использование цифр. В качестве идентификаторов нельзя применять ключевые слова языка и нежелательно переопределять встроенные имена. Список ключевых слов можно узнать так:
Имена, начинающиеся с подчеркивания или двух подчеркиваний, имеют особый смысл. Одиночное подчеркивание говорит программисту о том, что имя имеет местное применение, и не должно использоваться за пределами модуля. Двойным подчеркиванием в начале и в конце обычно наделяются специальные имена атрибутов - об этом будет говориться в лекции по объектно-ориентированному программированию.
В каждой точке программы интерпретатор "видит" три пространства имен: локальное, глобальное и встроенное. Пространство имен - отображение из имен в объекты. Для понимания того, как Python находит значение некоторой переменной, необходимо ввести понятие блока кода. В Python блоком кода является то, что исполняется как единое целое, например, тело определения функции, класса или модуля.
Локальные имена - имена, которым присвоено значение в данном блоке кода. Глобальные имена - имена, определяемые на уровне блока кода определения модуля или те, которые явно заданы в операторе global. Встроенные имена - имена из специального словаря __builtins__. Области видимости имен могут быть вложенными друг в друга, например, внутри вызванной функции видны имена, определенные в вызывающем коде. Переменные, которые используются в блоке кода, но связаны со значением вне кода, называются свободными переменными.
Так как переменную можно связать с объектом в любом месте блока, важно, чтобы это произошло до ее использования, иначе будет возбуждено исключение NameError. Связывание имен со значениями происходит в операторах присваивания, for, import, в формальных аргументах функций, при определении функции или класса, во втором параметре части except оператора try-except. С областями видимости и связыванием имен есть много нюансов, которые хорошо описаны в документации. Желательно, чтобы программы не зависели от таких нюансов, а для этого достаточно придерживаться следующих правил:
1. Всегда следует связывать переменную со значением (текстуально) до ее использования. 2. Необходимо избегать глобальных переменных и передавать все в качестве параметров. Глобальными на уровне модуля должны остаться только имена- константы, имена классов и функций. 3. Никогда не следует использовать from модуль import * - это может привести к затенению имен из других модулей, а внутри определения функции просто запрещено.
Предпочтительнее переделать код, нежели использовать глобальную переменную Конечно, для программ, состоящих из одного модуля, это не так важно: ведь все определенные на уровне модуля переменные глобальны.
Убрать связь имени с объектом можно с помощью оператора del. В этом случае, если объект не имеет других ссылок на него, он будет удален. Для управления памятью в Python используется подсчет ссылок (reference counting), для удаления наборов объектов с зацикленными ссылками - сборка мусора (garbage collection).
Все проблема в том, что Тебе кажется крайне черезжопными - мне кажется в порядке вещей. Мне просто думать нужно иначе. ООП -
Сообщение отредактировал serg-kkz - Вторник, 11.10.2011, 21:14