Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can modules have properties? [duplicate]

Is it possible to add properties and special methods to modules? I want to define a module such that importing it acts like a class instance, and the body acts as a class definition. Essentially, it's to avoid ugly syntax like this:

import game
if game.Game().paused:
    print("The game is paused")

E.g. the game module would look like this:

_Speed = 1

@property
def paused():
    return _Speed == 0

And the file using it:

import game
if game.paused:
    print("The game is paused")

Also, is it possible to define special methods (such as __call__)?

To be clear, I do not differentiate between class/instance methods, since I'm using game.Game as a singleton/borg class.

I have tested using @property and defining __bool__, but neither acts as I hoped.

Edit (information on why I want to use a property):

I have a property game.speed, a function game.paused() and a function game.pause(bool). Essentially, I have a temporary variable used to store the game speed when the game is paused. There is a private speed variable that is set to zero when the game is paused. I never want the user to see the speed as being zero, and be able to modify the speed while the game is paused, so that when the game is resumed, it uses the new speed.

like image 242
Casey Kuball Avatar asked Mar 30 '12 05:03

Casey Kuball


People also ask

Can two modules have functions with the same name?

It works fine. Both the function calls would be executed and we get the results. We have to be careful if two modules has same function with different parameters while importing.

What is module property?

Module property provides the default value for a module. Multiple process properties can source their value from a single module property. Module properties are defined at the module level and can be referenced by various resources that are defined as a part of the module.

Can a module contain a module?

A module can only contain declarations and functions to be used by other modules and programs. This is perhaps one of the most important difference. As a result, a module cannot exist alone; it must be used with other modules and a main program.

Can modules import each other?

Modules can import other modules. It is customary but not required to place all import statements at the beginning of a module (or script, for that matter). The imported module names, if placed at the top level of a module (outside any functions or classes), are added to the module's global namespace.


3 Answers

Python doesn't care that what's in sys.modules is actually a module. So you can just:

# game.py
class Game(object):
    pass

import sys
sys.modules["game"] = Game()

Now other modules that import game will get the Game instance, not the original module.

I'm not sure I recommend it, but it'll do what you want.

like image 155
kindall Avatar answered Sep 29 '22 21:09

kindall


If all you are looking for is the syntax as you mentioned, then you can define a class and use class level attributes

a1.py

class Game(object):
    paused = True


>>> from a1 import Game
>>> Game.paused
True
>>> Game.paused = False
>>> Game.paused
False

Well, as you asked about the Properties on Class, then you can do something with property decorator and classmethod. Soemthing like this

class ClassProperty(property):
    def __get__(self, cls, owner):
        return self.fget.__get__(None, owner)()

class Game(object):
    stage = True
    @ClassProperty
    @classmethod
    def paused(cls):
        return Game.stage == True

>>> from a1 import Game
>>> Game.paused
True
like image 25
Senthil Kumaran Avatar answered Sep 29 '22 21:09

Senthil Kumaran


It seems you want to avoid accessing items via the module. That's fairly easy to do.

These two are equivalent:

import game
if game.Game().paused:
    print("The game is paused")

from game import Game
if Game().paused:
    print("The game is paused")

Ok then, how about this:

# game.py

class Game(object):
    @property
    def paused():
        return True

game = Game()

# from your module
from game import game
game.paused
like image 45
Josh Smeaton Avatar answered Sep 29 '22 20:09

Josh Smeaton