2012-03-30 10 views
6

プロパティと特殊メソッドをモジュールに追加することはできますか?私はそれをインポートすることはクラスインスタンスのように動作し、ボディはクラス定義として動作するようにモジュールを定義したいと思います。基本的には、このような醜い構文を避けることです:モジュールはプロパティを持つことができますか?

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") 

はまた、(例えば__call__など)特別なメソッドを定義することは可能でしょうか?

私はgame.Gameをシングルトン/ borgクラスとして使用しているので、明確にするために、私はクラス/インスタンスメソッドを区別しません。

私は@propertyを使ってテストし、__bool__を定義しましたが、どちらも期待通りに動作しませんでした。

編集(私はプロパティを使用する理由に関する情報):

私は財産game.speed、機能game.paused()と機能game.pause(bool)を持っています。基本的には、一時停止時にゲームの速度を保存するための一時変数があります。ゲームが一時停止したときにゼロに設定されるプライベート速度変数があります。ユーザーが速度がゼロであると見なして、ゲームが一時停止している間に速度を変更できないようにして、ゲームが再開されるときに新しい速度を使用するようにすることは決してありません。

+2

「ゲームインポートゲームから」を使用するのはなぜですか? –

+0

プロパティはどのように機能しますか?メタクラス?メタクラスはどのようにGameクラスを参照していますか? – Darthfett

+2

'from ... import'構文を使用すると、*モジュールのプロパティは必要ないと言っています。あなたのモジュールを使っている人は、そこにプロパティがあるとは期待していないので、モジュールからプロパティを落として、自分のコードで単に 'form ... import'を使うと、読みやすさは同じですが、他のプログラマーの期待に合っています。それは良いことです。 –

答えて

11

PythonのようなSoemthingは何sys.modulesにありますが、実際にモジュールであることを気にしません。 import gameGameインスタンスを取得します

# game.py 
class Game(object): 
    pass 

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

さて、他のモジュールではなく、元のモジュール:だからあなただけのことができます。

私はそれをお勧めしますが、あなたが望むことをするでしょう。

+4

Whoa。それは黒い魔法です。 – bukzor

+0

よかった、ありがとう! :) – Darthfett

+1

それはある種の意味を作ります。結局、モジュール自体はクラスのインスタンス( 'types.ModuleType')です。実際には、 'Game'クラスをモジュールタイプのサブクラスとして記述し、インスタンス化することができます。次に、基本的にモジュールであるものを用意します。しかし、私が言ったように、Pythonは実際に型をチェックしません。 – kindall

0

これはうまくいきません。モジュールを複数回インポートする必要があり、Pythonはその内容を複数回実行します。そして、速度変数を再びリセットします。私はあなたがゲームの状態を格納する単一のGameクラスを使う方が良いと思います。また、コードをもっと明確にし、従うのが簡単になります。

+0

モジュールを一度実行したいのですが、問題は 'paused'のプロパティインターフェースを作成することです。 – Darthfett

+0

あなたのアプローチがうまくいかない理由です。状態を保存または計算するためのプロパティを持つクラスが必要です –

+0

シングルトン/ borgとして使用する必要がない場合はクラスを持っていないのではなく、使用するたびにインスタンスを作成します値。 – Darthfett

2

モジュール経由でアイテムにアクセスしたくないようです。それはかなり簡単です。

これら二つは等価です:

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

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

[OK]を、その後、どのようにこのことについて:あなたが述べたように、あなたが探しているすべての構文であれば、あなたはクラスを定義することができます

# game.py 

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

game = Game() 

# from your module 
from game import game 
game.paused 
+0

この構文は醜いです。 'self。*'や 'Game。*'のようなメンバを参照するメソッドや、(borgパターンのために)イニシャライザのハックを使うメソッドのために、シングルトン/ボルゴパターンを使うクラスを書く必要があります'__init__'を呼び出すたびにメンバを再設定します)。 – Darthfett

+0

2つ目は、最初にやろうとしていたものでしたが、ゲームに1つのモジュールが必要な場合は問題があることが判明し、モジュールはゲームのクラスインスタンスを要求します。それはあなたに次のようなエラーを与えます: 'ImportError:名前ゲームをインポートできません ' – Darthfett

+0

@Darthfett循環依存性?または私はあなたを誤解していますか?ゲームのインポートXとXのゲームをインポートしますか? –

3

とクラスレベルが

a1.py

class Game(object): 
    paused = True 


>>> from a1 import Game 
>>> Game.paused 
True 
>>> Game.paused = False 
>>> Game.paused 
False 
を属性を使用

あなたがProperties on Classについて質問したように、プロパティデコレータとクラスメソッドで何かできます。この

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 
+0

問題はプロパティの使用にあります。私は 'paused'が決して保存されないので、計算したい。 – Darthfett

+0

@Darthfett - 入手しました。私の答えを更新しました。 –

+1

あなたがリンクした答えによると、それはセッターのためには機能しません。私は[SSCCE](http://sscce.org/)を提供しようとしましたが、これについて言及していませんでしたが、私は他のゲームのメンバーにもセッターが必要です。 – Darthfett

関連する問題