Python 模块可以有属性吗?

Python 模块可以有属性吗?,python,properties,module,Python,Properties,Module,是否可以向模块添加属性和特殊方法?我想定义一个模块,这样导入它就像类实例一样,而主体就像类定义一样。本质上,这是为了避免像这样难看的语法: import game if game.Game().paused: print("The game is paused") _Speed = 1 @property def paused(): return _Speed == 0 例如,游戏模块如下所示: import game if game.Game().paused:

是否可以向模块添加属性和特殊方法?我想定义一个模块,这样导入它就像类实例一样,而主体就像类定义一样。本质上,这是为了避免像这样难看的语法:

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

@property
def paused():
    return _Speed == 0
例如,游戏模块如下所示:

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

@property
def paused():
    return _Speed == 0
以及使用它的文件:

import game
if game.paused:
    print("The game is paused")
此外,是否可以定义特殊方法(例如
\uuu调用\uuu

要明确的是,我不区分类/实例方法,因为我使用的是
game.game
作为单例/类

我已经使用@property和defining
\uuuubool\uuuuu
进行了测试,但两者都没有达到我的预期效果

编辑(有关为什么要使用属性的信息):


我有一个属性
game.speed
,一个函数
game.paused()
和一个函数
game.pause(bool)
。基本上,我有一个临时变量,用于在游戏暂停时存储游戏速度。游戏暂停时,有一个私人速度变量设置为零。我不希望用户看到速度为零,并且能够在游戏暂停时修改速度,以便在游戏恢复时使用新的速度。

我认为这是行不通的。您需要多次导入模块,Python将多次执行其内容。这将再次重置速度变量。我认为最好使用存储游戏状态的单个游戏类。它还将使您的代码更加清晰,易于理解。

您似乎希望避免通过模块访问项目。这很容易做到

这两个是等效的:

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

如果您要查找的只是您提到的语法,那么您可以定义一个类并使用类级属性

a1.py

class Game(object):
    paused = True


>>> from a1 import Game
>>> Game.paused
True
>>> Game.paused = False
>>> Game.paused
False
好的,正如您所问的,那么您可以使用属性装饰器和类方法做一些事情。像这样吗

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

Python并不关心
sys.modules
中的内容实际上是一个模块。所以你可以:

# game.py
class Game(object):
    pass

import sys
sys.modules["game"] = Game()
现在,
导入游戏的其他模块将获得
游戏
实例,而不是原始模块

我不确定我是否推荐它,但它可以满足您的需要。

这里的回答很好:

使用代理模式实现模块范围的属性。优雅

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项目)。

为什么不直接使用来自game import game的
?这些属性如何工作?元类?元类将如何引用游戏类?我是说如果您使用来自的
。。。导入
语法,您不需要模块上的属性。使用您的模块的人不会期望模块上有属性,因此如果您从模块中删除属性并简单地使用
表单。。。导入
在您自己的代码中,您可以获得相同的可读性,但您的API将更好地符合其他程序员的期望,这是一件好事。我更新了我的帖子,提供了更多信息。我有已计算的值,但应作为属性(与函数相反)。相关:--如果我将方法直接添加到模块对象,这是否可行?问题在于使用属性。我想计算
暂停的
,因为它从未被存储。@Darthfett-明白了。更新了我的答案。根据你链接的答案,它不适用于二传者。我试图给出一个实例,这就是为什么我没有提到这一点,但我也需要为游戏的其他成员提供setter。有没有理由你不能用实例属性定义类,不能在模块中将其实例定义为全局变量,不能从。。。导入
那样吗?是的,以这种方式设置程序可能不可行。使用Class变量设置状态如何?当然,它不是对称的,我想说你的实例化方法会更干净。我希望这个模块执行一次,我遇到的问题是为
暂停的
创建一个属性接口。这就是你的方法不起作用的原因。你需要一个具有属性的类来存储或计算状态我不反对拥有一个类,如果我不必将它用作singleton/borg,每次我想使用一个值时都要创建一个实例。这种语法很难看。它要求我编写一个类来使用singleton/borg模式,方法将成员引用为
self.*
Game.*
,并且(对于borg模式)使用初始化器hack(以避免每次调用
\uuu init\uuuu
都重新设置成员)。作为对第二个调用的响应,这是我最初尝试做的事情,但当我让游戏需要一个模块,然后那个模块需要游戏中的类实例时,问题就出现了。它会给你一个类似这样的错误:
importorror:无法导入名称游戏
@Darthfett循环依赖项?还是我误解了你?游戏导入X和X导入游戏?在Python中,我们是“同意的成年人”<代码>游戏
不是您界面的一部分;
game
实例是,因此在Pythonic视图中,不需要实例化控制“模式”。@Josh Smeaton是的,我不记得那个名字了。在我实际使用游戏中的东西时,所有东西都应该已经完全定义好了,所以如果我想导入一个全局文件,这只是个问题。哇。这是某种黑魔法,有一定的道理。毕竟,模块本身就是类的实例(
types.ModuleType
)。实际上,您可以将
游戏
类作为模块类型的子类编写,并实例化它,然后您就拥有了基本上是模块的东西。但正如我所说,Python实际上并没有检查类型。