2016-07-16 4 views
1

В настоящее время я создаю игровой сервер, на самом деле хочу сделать базовый проект для всех своих серверных продуктов в Python. Я использовал C#, но я хотел сделать что-то другое, поэтому я начал на Python. Хотя я не знаю, как это сделать.Python 'static core class'

В C# Я использовал один статический класс «core», содержащий все данные, содержащие точку входа, и там я загружаю сервер. Вот небольшой пример:

using System; 

namespace SERVER 
{ 
    public static class Engine 
    { 
     public static DatabaseHelper DatabaseHelper { get; private set; } 

     static void Main(string[] args) 
     { 
      DatabaseHelper = new DatabaseHelper(); 
     } 
    } 
} 

Тогда я только мог бы использовать в каждом классе:

Engine.DatabaseHelper.SomeMethod(); 

Теперь я хочу ту же концепцию в моем проекте Python, но я не знаю, как это сделать ,

Я получил этот первый:

DynamicEmu.py

import Engine 

engine = Engine.Engine() 

Engine.py

from Network.Game.GameConnectionListener import GameConnectionListener 


class Engine: 
    gameConnection = None 

    def __init__(self): 
     gameConnection = GameConnectionListener() 

    def tuple_to_addr(self, tpl): 
     return '{0}:{1}'.format(tpl[0], str(tpl[1])) 

А потом в моей GameConnectionListener.py я хотел бы использовать:

import DynamicEmu 

Для того, чтобы сделать

DynamicEmu.engine.tuple_to_addr(TUPLE HERE) 

Но я получаю эту ошибку

Traceback (most recent call last): 
    File "C:/Users/Josh/PycharmProjects/DynamicEmu/DynamicEmu.py", line 1, in <module> 
    import Engine 
    File "C:\Users\Josh\PycharmProjects\DynamicEmu\Engine.py", line 3, in <module> 
    from Network.Game.GameConnectionListener import GameConnectionListener 
    File "C:\Users\Josh\PycharmProjects\DynamicEmu\Network\Game\GameConnectionListener.py", line 4, in <module> 
    import DynamicEmu 
    File "C:\Users\Josh\PycharmProjects\DynamicEmu\DynamicEmu.py", line 3, in <module> 
    engine = Engine.Engine() 
AttributeError: module 'Engine' has no attribute 'Engine' 

Я сосу в Python, так что если я делаю что-то действительно неправильно я понимаю, я хочу узнать, так что я оценил бы каждую часть помощи, я могу get :)

+0

У вас есть круговая зависимость: вам нужен объект 'Engine' для создания' GameConnectionLIstener', но вам нужно 'GameConnectionListener' для создания' Engine'. – chepner

+0

Хм, да, ты прав, я понимаю, каким образом я могу сделать что-то вроде моего примера на C#? –

+2

Я не знаю, что еще делает '' Engine', но 'tuple_to_addr' не использует' self', поэтому я не знаю, почему он является частью класса 'Engine'. Сделайте его автономной функцией вне класса. (Он может работать в том же модуле, но я бы его перемещал, циклический импорт не обязательно был проблемой, но вы все равно должны избегать их.) – chepner

ответ

2

Типичный код Python не использует статические элементы. Поэтому я бы посоветовал сделать большинство переменных экземпляра переменных. Например, в DynamicEmu.py не имеют экземпляра модуля Engine. Вместо этого, есть класс, который инициализируется с Engine например

class DynamicEmu: 
    def __init__(self, engine): 
     self.engine = engine 
    ... 

или функцию, которая принимает Engine экземпляр в качестве аргумента

def dynamic_emu(engine): 
    ... 

Трудно быть более конкретным, не зная, что код в DynamicEmu.py должен делать.

Точно так же, в GameConnectionListener.py вы должны определить ваш слушатель как

class GameConnectionListener: 
    def __init__(self, engine): 
     self.engine = engine 
    ... 

и так далее с другим кодом. (Имейте в виду, что функции Python являются объектами и могут передаваться как аргументы и использоваться как обратные вызовы. Подумайте, можно ли уйти от функции, а не класса.)

Очевидно, что экземпляр Engine должен быть создан где-то , Логическое место может быть в вашей функции main() или в некоторой функции настройки, которая вызывается в начале программы. Затем вы можете передать его другим функциям и методам по мере необходимости.

По моему опыту, писать большой проект, как правило, лучше, когда вы четко понимаете зависимости между различными частями кода. Например, будьте ясны о том, использует ли игровой движок слушатель или слушатель использует движок игры. Если двигатель использует слушателя, то вы должны использовать GameConnectionListener в Engine, но не наоборот. GameConnectionListener должен быть спроектирован таким образом, чтобы он не знал о Engine. Конечно, это не всегда возможно, но в какой бы степени вы этого ни делали, я думаю, что это помогает. Это уменьшает или устраняет круговые зависимости, как у вас в вашем примере кода, а также помогает писать каждый компонент программы отдельно, не беспокоясь о других одновременно.


Или, что C# вызывает статических членов; в Python их называют членами класса, но почти такая же функциональность часто предоставляется переменными уровня модуля, которые проще.

+0

Я вижу, что вы делаете в основном, это передача аргументов, почему я не думал об этом раньше? Раньше я учился в школе о передаче аргументов (и я тоже это делал на Java, потому что мне пришлось lol). Спасибо за вашу помощь! Только один вопрос, как насчет импорта в обоих этих файлах, поскольку это может иметь значение? –

+0

Вам даже не нужно импортировать 'Engine.py' из' DynamicEmu.py' или 'GameConnectionListener.py'. В Python нет необходимости импортировать модуль только для использования экземпляра класса, определенного в этом модуле. Вам нужно только импортировать модуль, если вы хотите инициализировать класс, или получить доступ к одной из переменных или функций на уровне модуля. Я бы посоветовал прочитать [этот другой вопрос] (https://stackoverflow.com/questions/3188929/why-import-when-you-need-to-use-the-full-name) и мой ответ на него. (Это касается Java, но я думаю, что C# аналогичен в этом отношении.) –

+0

Это мне не нужно импортировать, потому что нет определения типа, когда я помещаю параметр 'engine' в' def'? –