是否可以为模块添加属性和特殊方法?我想定义一个模块,以便导入它就像一个类实例,并且正文充当类定义。从本质上讲,要避免像这样的丑陋语法:
import game
if game.Game().paused:
print("The game is paused")
E.g。游戏模块看起来像这样:
_Speed = 1
@property
def paused():
return _Speed == 0
使用它的文件:
import game
if game.paused:
print("The game is paused")
此外,是否可以定义特殊方法(例如__call__
)?
要明确的是,我没有区分类/实例方法,因为我使用game.Game
作为单例/ borg类。
我已经使用@property进行了测试并定义了__bool__
,但都没有像我希望的那样行事。
编辑(有关我为何要使用属性的信息):
我有一个属性game.speed
,一个函数game.paused()
和一个函数game.pause(bool)
。从本质上讲,我有一个临时变量,用于在游戏暂停时存储游戏速度。有一个私人速度变量在游戏暂停时设置为零。我从不希望用户将速度视为零,并且能够在游戏暂停时修改速度,以便在游戏恢复时使用新的速度。
答案 0 :(得分:12)
Python并不关心sys.modules
中的内容实际上是一个模块。所以你可以:
# game.py
class Game(object):
pass
import sys
sys.modules["game"] = Game()
现在import game
将获得Game
实例的其他模块,而不是原始模块。
我不确定我是否推荐它,但它会做你想要的。
答案 1 :(得分:3)
如果您要查找的只是您提到的语法,那么您可以定义一个类并使用类级别属性
a1.py
class Game(object):
paused = True
>>> from a1 import Game
>>> Game.paused
True
>>> Game.paused = False
>>> Game.paused
False
好吧,当你问到Properties on Class时,你可以用属性装饰器和classmethod做些什么。像这样的东西
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
答案 2 :(得分:2)
您似乎希望避免通过模块访问项目。这很容易做到。
这两个是等价的:
import game
if game.Game().paused:
print("The game is paused")
from game import Game
if Game().paused:
print("The game is paused")
好的,那怎么样:
# game.py
class Game(object):
@property
def paused():
return True
game = Game()
# from your module
from game import game
game.paused
答案 3 :(得分:0)
我不认为这会起作用。您需要多次导入模块,Python将多次执行其内容。这将再次重置速度变量。我认为你最好使用一个存储游戏状态的Game类。它还可以使您的代码更清晰,更容易理解。
答案 4 :(得分:0)
好的答案在这里:
http://jtushman.github.io/blog/2014/05/02/module-properties/
使用代理模式来实现模块范围的属性。优雅。
class Proxy(object):
def __init__(self, local):
self.local = local
def __getattr__(self, name):
return getattr(self.local(), name)
# aliasing for better syntax
module_property = Proxy
class User(object):
"""Contrived User Object"""
def __init__(self, **kwargs):
self.name = kwargs.get('name', 'billy')
def speak(self):
print("Well hello there!")
def say_hi(self, to_whom):
print("Hi there {}".format(to_whom))
@module_property
def current_user():
return User()
然后可以将其用作属性:
from login_manager import current_user, User
if __name__ == '__main__':
print current_user.name
current_user.speak()
current_user.say_hi('lauren')
文章还提到了扩展此概念的可安装软件包(werkzerg项目)。