Python: best way to call methods from another class?

I have the following code:

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 is an array that is defined outside of this class, so this code does not work. Since there are likely to be many other functions in this class that might use the aGame array, I have to do this:

 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 

Or it would be better to do this:

 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 

Or do I need to make aGame a global variable (if so, how, note that this class is in another file)?

Since aGame is an array that is used everywhere, it does not seem right to make copies of it inside each class. Maybe I'm wrong, I'm slowly learning OOP, so thanks for any help.

+4
source share
4 answers

In my opinion, the first option is right, because it uses global variables for no good reason. Thus, the choice between the second and third.

The decisive feature is that you want to use the same instance of Player for more than one aGame value. If there was ever only one value, then I would either pass it to the constructor (your option 2) or use the idea of ​​gnibbler to make it a class variable. I would prefer to pass it to the constructor for ease of testing.

If you want the same Player instance to be used with multiple aGame values, then option 3 is probably the cleanest way to achieve this.

+3
source

Only the first choice will work. In the second example, for room in self.aGame['rooms'] will lead to an error, because nowhere aGame is not attached to itself. It will work if it was for room in aGame['rooms'] , but then you have to unnecessarily pass aGame every time you call move() .

You can also make a global variable, but it is best that each player has an aGame instance. If you need to modify aGame and have multiple players, you must define it as a global variable.

It’s also just nitpicking, but aGame not an array, it is a dictionary. The Python language does not even have arrays (although some extensions are performed).

0
source

Is aGame same for every instance? Then you can make it an attribute of the class either like this

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

or

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

Inside the class, you can access it through self.aGame

0
source

I would use a small change in the global:

 # 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']: # ... 

Alternatively, you can make the game a suitable class, assign Game.instance = Game (...) somewhere during the initialization phase and get more real singleton pattern.

0
source

Source: https://habr.com/ru/post/1337246/


All Articles