Проверка членское существование в Python

Есть 3 способа сделать это, но решение этого зависит от типа данных, которые вы хотите передать между сценами. Компоненты / скрипты и GameObjects уничтожаются при загрузке новой сцены и даже при маркировке как static.

1. Используйте ключевое слово static.

Используйте этот метод, если переменная для перехода к следующей сцене не является компонентом, не наследуется от MonoBehaviour и не является GameObject затем сделайте переменную равной static.

Встроенные примитивные типы данных, такие как int, bool, string, float, double. Все эти переменные могут быть сделаны переменной static.

Пример встроенных примитивных типов данных, которые могут быть отмечены как статические:

static int counter = 0;
static bool enableAudio = 0;
static float timer = 100;

Они должны работать без проблем.


Пример объектов, которые может быть отмечен как статический:

public class MyTestScriptNoMonoBehaviour
{

}

, затем

static MyTestScriptNoMonoBehaviour testScriptNoMono;

void Start()
{
    testScriptNoMono = new MyTestScriptNoMonoBehaviour();
}

Обратите внимание, что класс не наследуется от MonoBehaviour . Это должно работать.


Пример объектов, которые не может быть помечены как статические:

Все, что наследуется от Object , Component или GameObject не будет работать.

1A. Все, что наследуется от MonoBehaviour

public class MyTestScript : MonoBehaviour 
{

}

then

static MyTestScript testScript;

void Start()
{
    testScript = gameObject.AddComponent();
} 

Это не будет работать, потому что оно наследуется от MonoBehaviour .

1B.All GameObject :

static GameObject obj;

void Start()
{
    obj = new GameObject("My Object");
}  

Это не сработает, потому что это GameObject и GameObject наследуются от Object .

Единство всегда будет уничтожать его Object , даже если они объявлены с ключевым словом static.

См. № 2 для обходного пути.


2.Используйте функцию DontDestroyOnLoad .

Вам нужно использовать это, только если данные сохранить или перейти к следующей сцене наследует от Object , Component или является GameObject . Это решает проблему, описанную в 1A и 1B.

Вы можете использовать ее, чтобы этот GameObject не уничтожался при выгрузке сцены:

void Awake() 
{
    DontDestroyOnLoad(transform.gameObject);
}

Вы даже можете использовать его с ключевыми словами static решить проблему из 1A и 1B:

public class MyTestScript : MonoBehaviour 
{

}

then

static MyTestScript testScript;

void Awake() 
{
    DontDestroyOnLoad(transform.gameObject);
}

void Start()
{
    testScript = gameObject.AddComponent();
} 

Теперь переменная testScript будет сохранена при загрузке новой сцены.

3. Сохраните локальную память, затем загрузите ее во время следующей сцены.

Этот метод следует использовать, когда это данные игры, которые необходимо сохранить, когда игра закрыта и снова открыта. Пример этого - высокий балл игрока, настройки игры, такие как громкость музыки, местоположения объектов, данные профиля джойстика и т. Д.

Thare - два способа сохранить это:

3A. Используйте API PlayerPrefs .

Используйте, если у вас есть только несколько переменных для сохранения. Скажем, оценка игрока:

int playerScore = 80;

И мы хотим сохранить playerScore:

Сохранить оценку в функции OnDisable

void OnDisable()
{
    PlayerPrefs.SetInt("score", playerScore);
}

Загрузить в функции OnEnable

void OnEnable()
{
    playerScore  =  PlayerPrefs.GetInt("score");
}

3B. Сериализуйте данные в форму json, xml или binaray, затем сохраните с помощью одного из файлов API C #, таких как File.WriteAllBytes и File.ReadAllBytes для сохранения и загрузки файлов.

Используйте этот метод, если есть много переменных для сохранения.

Общие сведения, вам необходимо создать класс, который не наследуется от MonoBehaviour . Этот класс, который вы должны использовать для хранения ваших игровых данных, чтобы их можно было легко сериализовать или де-сериализовать.

Пример данных для сохранения:

[Serializable]
public class PlayerInfo
{
    public List ID = new List();
    public List Amounts = new List();
    public int life = 0;
    public float highScore = 0;
}

Возьмите класс DataSaver, который является оберткой поверх File.WriteAllBytes и File.ReadAllBytes , который упрощает сохранение данных из этого сообщения .

Создать новый экземпляр:

PlayerInfo saveData = new PlayerInfo();
saveData.life = 99;
saveData.highScore = 40;

Сохранить данные из PlayerInfo в файл с именем «игроки»:

DataSaver.saveData(saveData, "players");

Загрузить данные из файла с именем «игроки»:

PlayerInfo loadedData = DataSaver.loadData("players");

26
задан PierreBdR 15 October 2008 в 23:23
поделиться

5 ответов

Это две различных методологии: в „–1 является LBYL (взгляд перед прыганием), и в „–2 является EAFP (легче спросить прощение, чем разрешение).

Pythonistas обычно предполагают, что EAFP лучше с аргументами в стиле, "что, если процесс создает файл между временем, Вы тестируете на него и время, Вы пытаетесь создать его сами?". Этот аргумент не применяется здесь, но это - общее представление. Исключения нельзя рассматривать как также исключительный.

мудрый Производительностью в Вашем случае — начиная с установки менеджеров по исключению (try ключевое слово) является очень дешевым в CPython, в то время как создание исключения (raise ключевое слово и создание внутренней исключительной ситуации) - то, что относительно expensive— использование метода в „–2, исключение было бы повышено только однажды; впоследствии, Вы просто используете свойство.

22
ответ дан tzot 19 July 2019 в 06:05
поделиться

Я просто попытался измерить времена:

class Foo(object):
    @classmethod
    def singleton(self):
        if not hasattr(self, 'instance'):
            self.instance = Foo()
        return self.instance



class Bar(object):
    @classmethod
    def singleton(self):
        try:
            return self.instance
        except AttributeError:
            self.instance = Bar()
            return self.instance



from time import time

n = 1000000
foo = [Foo() for i in xrange(0,n)]
bar = [Bar() for i in xrange(0,n)]

print "Objs created."
print


for times in xrange(1,4):
    t = time()
    for d in foo: d.singleton()
    print "#%d Foo pass in %f" % (times, time()-t)

    t = time()
    for d in bar: d.singleton()
    print "#%d Bar pass in %f" % (times, time()-t)

    print

На моей машине:

Objs created.

#1 Foo pass in 1.719000
#1 Bar pass in 1.140000

#2 Foo pass in 1.750000
#2 Bar pass in 1.187000

#3 Foo pass in 1.797000
#3 Bar pass in 1.203000

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

10
ответ дан Andrea Ambu 19 July 2019 в 06:05
поделиться

Это зависит, на котором случай "типичен", потому что исключения должны смоделировать, ну, в общем, нетипичные условия. Так, если типичный случай - то, что эти instance атрибут должен существовать, затем используйте второй стиль кода. Не имение instance так же типично как наличие instance, то используйте первый стиль.

В конкретном случае создания одиночного элемента, я склонен пойти с первым стилем, потому что, создавая одиночный элемент начальное время является типичным вариантом использования.:-)

5
ответ дан Chris Jester-Young 19 July 2019 в 06:05
поделиться

Немного вне темы в способе использовать его. Одиночные элементы переоценены, и метод "общего состояния" является столь же эффективным, и главным образом, очень чистым в Python, например:

class Borg:
    __shared_state = {}
    def __init__(self):
        self.__dict__ = self.__shared_state
    # and whatever else you want in your class -- that's all!

Теперь каждый раз Вы делаете:

obj = Borg()

это будет иметь ту же информацию, или, будет несколько тем же экземпляром.

1
ответ дан gx. 19 July 2019 в 06:05
поделиться

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

я действительно видел http://code.activestate.com/recipes/52558/ как способ сделать это, также. Непрокомментированная копия того кода ("спам" является просто случайным методом интерфейс класса, имеет):

class Singleton:
    class __impl:
        def spam(self):
            return id(self)
    __instance = None
    def __init__(self):
        if Singleton.__instance is None:
            Singleton.__instance = Singleton.__impl()
        self.__dict__['_Singleton__instance'] = Singleton.__instance
    def __getattr__(self, attr):
        return getattr(self.__instance, attr)
    def __setattr__(self, attr, value):
        return setattr(self.__instance, attr, value)
0
ответ дан Brian 19 July 2019 в 06:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: