[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 2
  • 1
  • 2
  • »
Форум Panda3D - по русски » Общий форум » Python » Модули (Изменения значений из другого модуля)
Модули
serg-kkzДата: Суббота, 08.10.2011, 22:30 | Сообщение # 1
Генерал-полковник
Группа: Модераторы
Сообщений: 803
Награды: 3
Репутация: 18
Статус: Offline
Странная штука модульность, в питоне.

Пример, файл main.py:
Code
import module1
module1.Start1()
import module2
module2.Start2()


Первый модуль, содержит словарь:
Code
class Start1():
     def __init__(self):
         self.a = {'s':'eee'}

Второй модуль должен, изменить значение ключа 's':
Code
import module1
class Start2():
     def __init__(self):
         module1.Start1().a['s'] = 'fffffdddd'
         print module1.Start1().a


А в итоге, фиг меняет. Если память мне не изменяет в бейсике с этим нет проблем. Или может я что-то делаю не так? Сделал модуль для отображеня gui, теперь нужно скрывать или отображать элементы из других модулей. Например из модуля загрузчика, отобразить фон для загрузки. Или прийдется в нем gui создавать. При таком раскладе, пользы от них. dry


ООП  -  
 
ninthДата: Воскресенье, 09.10.2011, 23:43 | Сообщение # 2
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
Code
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
 
serg-kkzДата: Понедельник, 10.10.2011, 00:32 | Сообщение # 3
Генерал-полковник
Группа: Модераторы
Сообщений: 803
Награды: 3
Репутация: 18
Статус: Offline
Не до конца в ехал.

Вот пример, когда мне все ясно. Мне ясно, когда при вызове модуля ему можно передать значение аргументом, который он обработает.

Code
class Start1():
        def __init__(self):
            self.a = {'s':'eee'}

St1 = Start1()
          
class Start2():
        def __init__(self):
            St1.a['s'] = 'fffffdddd'
   
St2 = Start2()

print St1.a


В таком представление имен и доступа по ним к значениям, мне намного лучше ориентироваться, когда все в куче)


ООП  -  
 
ninthДата: Понедельник, 10.10.2011, 01:53 | Сообщение # 4
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
Посмотри внимательно 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'      

St2 = Start2(St1)    

print St1.a
 
serg-kkzДата: Понедельник, 10.10.2011, 11:33 | Сообщение # 5
Генерал-полковник
Группа: Модераторы
Сообщений: 803
Награды: 3
Репутация: 18
Статус: Offline
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, хотел выдрать тени, а там сплошные аргументы как паутина. Все-таки выдрал, с кучей странных модулей. Которые и не нужны, а выкинешь, не работает. Полез удалять все ссылки, голову сломал =)


ООП  -  
 
ninthДата: Понедельник, 10.10.2011, 14:17 | Сообщение # 6
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
Quote (serg-kkz)
Где все логично.

Категорически не согласен. Использование в корне неправильное. Зачем вообще тогда классы модули, ели ты не можешь их спокойно выдернуть куда тебе надо? При такой работе как пытаешься организовать ты, в конце концов ты получишь рекурсивные ссылки в модулях друг на друга.

Если уж очень хочется работать так, то заноси нужные переменные в __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'    
                
        def print_text(self):    
             print St1.a    
      
St2 = Start2()    
    
St2.print_text()
 
serg-kkzДата: Понедельник, 10.10.2011, 16:24 | Сообщение # 7
Генерал-полковник
Группа: Модераторы
Сообщений: 803
Награды: 3
Репутация: 18
Статус: Offline
Чем дальше в лес, тем темней =) Зачем мне __builtin__? когда все в куче работает и без него. А вот если вынести, то это не поможет. Ведь при импортировании модуля питон матерится на St1, даже не смотря St1 = Start1() что был запущен, или прокатит? И что мне не дает настроенный класс использовать в другом месте? Например Start1() там будут в словаре ноды гуи, и я смогу без проблем управлять их параметрами из других классов. Например из автомата или пистолета?! какие-то проблемы. Я просто к тому что логику дробить на кучу файлов ни к чему. Все равно его не получится использовать где нужно, например гнома, интересно куда его можно запихать? причем без правки, импортировал его и он запустился.

ООП  -  
 
ninthДата: Понедельник, 10.10.2011, 21:03 | Сообщение # 8
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
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'        
                     
         def print_text(self):        
              print St1.a     
 
serg-kkzДата: Понедельник, 10.10.2011, 21:45 | Сообщение # 9
Генерал-полковник
Группа: Модераторы
Сообщений: 803
Награды: 3
Репутация: 18
Статус: Offline
Все ясно, только мне мыслить надо как то по-другому. Видимо мне привился неправильный стиль =). А, вот насчет большого файла как то не задумался. Замечу модуль гнома содержит несколько классов, и чтоб его совершенствовать их нужно дорабатывать, тем самым опять увеличивать размер. Вот с вариантом __builtin__ мне как раз удобно, ну теперь не пойму что плохого в ссылках друг на друга? чем чревато?

ООП  -  
 
ninthДата: Вторник, 11.10.2011, 10:51 | Сообщение # 10
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
Quote (serg-kkz)
чем чревато?

Незапуском программы и чесанием репы из разряда "а как это теперь совмещать если мне надо и то и то"?
 
serg-kkzДата: Вторник, 11.10.2011, 14:30 | Сообщение # 11
Генерал-полковник
Группа: Модераторы
Сообщений: 803
Награды: 3
Репутация: 18
Статус: Offline
Quote (ninth)
Незапуском программы и чесанием репы из разряда "а как это теперь совмещать если мне надо и то и то"?

Ну такого быть не может, я не говорил что мне нужны ссылки на все переменные в классах. Например глупо в классе автомата иметь ссыль на пистолет. Я говорил о классах которые формируют архитектуру игры, вот они по моему должны быть доступны из этих классов, к примеру для оружия - HUD. Если мы создали экземпляр автомата, то он конфигурирует класс GUI - HUD и другии нужные. Например меняет размер прицела при стрельбе, на основании параметров которые прописанные в файле характеристик и считываются при инициализации класса. А далее распределяются нужным классам логики игры, которые являются только каркасом и без них логика не может существовать. При таком подходе легко написать инструменты для создания карт, персонажей и т.д. просто оперируя файлами параметров.

Данный подход везде и повсюду в играх. Возмем также NeoAxis там все в классах. Любой игровой объект - класс. Стоит заметить логика при таком подходе хочень раздробленна, и это дает гибкость. И по сути вопроса не возникает как что-то совмещать. Не думаю что логика игры рухнет если скажем не создать экземляр класса автомата =) Ведь ссылок на него нет из каркаснах классов, к примеру опять HUD.


ООП  -  
 
soosДата: Вторник, 11.10.2011, 16:51 | Сообщение # 12
Майор
Группа: Пользователи
Сообщений: 82
Награды: 1
Репутация: 0
Статус: Offline
Чот тут всё в кучу намешано: модули, классы, экземпляры класса, члены класса, методы класса, пространства имён. Нужно хотя бы базовые принципы питона понимать, чтобы такими понятиями оперировать.
 
serg-kkzДата: Вторник, 11.10.2011, 17:17 | Сообщение # 13
Генерал-полковник
Группа: Модераторы
Сообщений: 803
Награды: 3
Репутация: 18
Статус: Offline
soos, ой-ё, прости больше не буду=) не буду, не буду даже думать об этом. Может понимающий, че по теме скажет? Просветит, если Вам не трудно.

ООП  -  
 
soosДата: Вторник, 11.10.2011, 19:33 | Сообщение # 14
Майор
Группа: Пользователи
Сообщений: 82
Награды: 1
Репутация: 0
Статус: Offline
Сарказм? Сарказм - это хорошо (: Если мой тон показался слишком высокомерным, так это я не со зла, такая уж у меня манера изложения конструктивной критики.
Я, честно говоря, не понял какая цель преследуется при разбиении на модули? По идее модули и классы нужны, чтобы "прятать" логику работы конкретного куска кода в, соответственно, модуль или класс. И чтобы тот, кто использует этот модуль или класс использовал только интерфейс, который для него создал разработчик этого модуля или класса.
В конкретном примере мне непонятно как классы Start1 и Start2 связаны? Либо Start2 наследуется от Start1, либо Start2 использует экземпляр класса Start1. Остальные способы взаимодействия двух классов представляются мне крайне черезжопными.
 
serg-kkzДата: Вторник, 11.10.2011, 21:05 | Сообщение # 15
Генерал-полковник
Группа: Модераторы
Сообщений: 803
Награды: 3
Репутация: 18
Статус: Offline
Quote (soos)
Сарказм? Сарказм - это хорошо (: Если мой тон показался слишком высокомерным, так это я не со зла, такая уж у меня манера изложения конструктивной критики.

Ты конструктивно сказал: не понимаете, а говорите. Зачем? Или как понять что-то не говоря об этом? Может и учиться не надо, раз нет понимания? Может при обсуждении темы жесты использовать или сравнивать с банальными понятиями.

Ладно: Как мне написанные буквы изобразить в одном месте и в другом, без появления черного прямоугольника с какими-то буквами, что тужно сделать? Мне так-же интересно знать как буквы запихать в другие буквы?



Все проблема в том, что Тебе кажется крайне черезжопными - мне кажется в порядке вещей. Мне просто думать нужно иначе.


ООП  -  

Сообщение отредактировал serg-kkz - Вторник, 11.10.2011, 21:14
 
Форум Panda3D - по русски » Общий форум » Python » Модули (Изменения значений из другого модуля)
  • Страница 1 из 2
  • 1
  • 2
  • »
Поиск: