Python: Лучший способ вызвать методы из другого класса? - PullRequest
4 голосов
/ 27 января 2011

У меня есть следующий код:

class Player:
    def __init__(self, username, trip, model):
        self.username = username
        self.trip = trip
        self.hp = 100


    #### For player moving location/room ####
    def Move(self, dest):
        if dest == self.loc:
            return True

        # Check destination room is accessible from current room
        for room in aGame['rooms']:
            if room['ref'] == self.loc:
                for acsroom in room['acs']:
                    if acsroom == dest:
                        self.loc = dest
                        return True
        return False

aGame - это массив, который определен вне этого класса, поэтому этот код не работает.Поскольку в этом классе, вероятно, будет много других функций, которые, возможно, будут использовать массив aGame, я должен сделать следующее:

class Player:
    def __init__(self, username, trip, model, aGame):
        self.username = username
        self.trip = trip
        self.hp = 100
        self.aGame = aGame            

    #### For player moving location/room ####
    def Move(self, dest):
        if dest == self.loc:
            return True

        # Check destination room is accessible from current room
        for room in self.aGame['rooms']:
            if room['ref'] == self.loc:
                for acsroom in room['acs']:
                    if acsroom == dest:
                        self.loc = dest
                        return True
        return False

Или лучше сделать это:

class Player:
    def __init__(self, username, trip, model):
        self.username = username
        self.trip = trip
        self.hp = 100          

    #### For player moving location/room ####
    def Move(self, dest, aGame):
        if dest == self.loc:
            return True

        # Check destination room is accessible from current room
        for room in aGame['rooms']:
            if room['ref'] == self.loc:
                for acsroom in room['acs']:
                    if acsroom == dest:
                        self.loc = dest
                        return True
        return False

Или я должен сделать aGame глобальной переменной (если да, то как, обратите внимание, что этот класс находится в другом файле)?

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

Ответы [ 4 ]

3 голосов
/ 27 января 2011

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

Решающая особенность заключается в том, хотите ли вы использовать один и тот же экземпляр Player для более чем одного значения aGame.Если когда-либо будет только одно значение, я либо передам его конструктору (ваш вариант 2), либо воспользуюсь идеей gnibbler сделать его переменной класса.Я бы, вероятно, предпочел бы передать его конструктору для простоты тестирования.

Если вы хотите, чтобы один и тот же экземпляр Player мог использоваться с несколькими значениями aGame, тогда вариант 3, вероятно, является самым чистым способом достижения этого,

0 голосов
/ 27 января 2011

aGame одинаково для каждого экземпляра? Тогда вы можете сделать его атрибутом класса, например,

class Player:
    aGame={'rooms':...}
    ...

или

Class Player:
    ...

Player.aGame={'rooms':...}

В классе вы все равно можете получить к нему доступ через self.aGame

0 голосов
/ 27 января 2011

Я бы использовал небольшое изменение для глобального:

# in game.py or whatever
class Game(object):
    instance = {} # this is your aGame array

# in player.py or whatever:
from game import Game

class Player(object):
    # ...
    def Move(self, dest):
        # ...
        for room in Game.instance['rooms']:
            # ...

В качестве альтернативы, вы можете сделать Game подходящим классом, назначить Game.instance = Game (...) где-нибудь на этапе инициализации и получить больше реальных одноэлементных шаблонов.

0 голосов
/ 27 января 2011

Только первый выбор будет работать. Во втором примере for room in self.aGame['rooms'] выдаст ошибку, потому что нигде игра не привязана к себе. Это сработало бы, если бы оно было for room in aGame['rooms'], но тогда вам пришлось бы без необходимости передавать aGame каждый раз, когда вы звоните move().

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

Кроме того, просто придирки, но aGame это не массив, это словарь. Язык Python даже не имеет массивов (хотя некоторые расширения имеют).

...