1

関数がある場合:

def foo(self, a, b):
    c = a + b
    return c

関数内の c を変更せずに foo を呼び出すにはどうすればよいですか? それでは、別の関数で foo を呼び出すとしましょう:

def bar(self):
    z = self.foo(2, 4)
    return (z)

そして、別の関数で foo を再度呼び出したいのですが、'bar' が呼び出された時点から c が必要です。

def baz(self):
    self.foo(?, ?) # trying to just get c, without any changes.

基本的に、他のクラスが同じアカウントにアクセスできるように、クラスにアカウントを保持しようとしています。お金を足したり引いたりする単純なバランスです。

ありがとう。

4

6 に答える 6

5

クラス変数またはグローバルcとして保存し、関数をオーバーライドして古い値を返します。

例えば

class SomeClass:
     def foo(self, a=None, b=None):
        if a and b:
            c = a + b
            self.stored_c = c
            return c
        return self.stored_c

注: 更新のタイミングstored_cと同時実行の問題を処理する必要があります。

更新: WRT glglglのコメント、メソッドのオーバーロードについて更新。

于 2012-08-20T12:50:02.530 に答える
3

ローハンが答えとして提供したものを取り上げて、次のことを考え出しました. これを達成するためのより良い/好ましい方法があるかもしれませんが、うまくいくようです。

次のコードを使用すると、複数のクラスとメソッドにわたって口座残高を追跡できます。

import os

class Foo():
    def __init__(self):
        self.stored_end = 0

    def account(self, a, b):
        c = float(a) + b
        print a
        print b
        print c
        self.stored_end = c
        print self.stored_end

    def testy(self, q, v):
        print "\n"
        print " _ " * 10
        z = float(q) + v
        print self.stored_end   
        self.stored_end = self.stored_end + z
        print " _ " * 10
        print self.stored_end

class Bar():
    def __init__(self):
        pass

    def zippy(self, a, b):
        print " _ " * 10
        print "this is zippy"
        foo.testy(a, b)

class Baz():
    def __init__(self):
        pass

    def cracky(self, g, m):
        y = g + m
        print " _ " * 10
        print "calling stored_end"
        foo.stored_end = foo.stored_end + y
        print " _ " * 10
        print "this is cracky"
        print "y = %r" % y
        print foo.stored_end    

os.system("clear")      
foo = Foo()
foo.account(5, 11)
foo.testy(100, 100)
bar = Bar()
bar.zippy(10, 100)
baz = Baz()
baz.cracky(1000, 1)
于 2012-08-20T17:36:48.797 に答える
3

c関数に対してローカルであり、静的ではありません。つまり、関数が終了するたびに、cガベージ コレクションが取得されます。c最初に計算された値を保存しないのはなぜですか? 当たり前の答えのようです。

于 2012-08-20T12:51:16.327 に答える
2

最後の結果を保存するには、いくつかの構造が必要です。たとえば、関数にラッパーを実行できます。

def keep_result(func):
    from functools import wraps
    @wraps(func)
    def wrapper(*a, **k):
        res = func(*a, **k)
        wrapper.last_result = res
        return res
    wrapper.func = func # makes it easy to bypass
    return wrapper

これがいわゆる「デコレータ関数」です。

今あなたがするなら

@keep_result
def foo(self, a, b)
    c = a + b
    return c

関数(その結果ではなく、それ自体) は、元の関数を呼び出し、その結果を属性に保存し、結果を返す新しい関数を作成するfoo引数として使用されます。この新しい関数は、元の関数の代わりに返されます。keep_result()wrapper()foo()

だからあなたは言うことができます

normal_result = foo(whatever)

そして、する

saved_result = foo.last_result

そしてあなたは同じことを得る。

于 2012-08-20T12:58:55.403 に答える
1

あなたが望むのはキャッシュされたプロパティのようです。将来使用する一般的なものとしてそれを行う記述子を実装するデコレータを作成できます。

def cachedproperty(f):
    """Cached property.

    Calculated once - serves forever.
    """

    def get(self):
        try:
            return self._properties[f]
        except AttributeError:
            self._properties = {}
            self._properties[f] = f(self)
            x = self._properties[f]
            return x
        except KeyError:
            x = self._properties[f] = f(self)
            return x

    return property(get)

例を見てみましょう:

 class X(object):
     x = 0

     def __init__(self, x):
         self.x = x

     @cachedproperty
     def y(self):
         return self.x + 6

ここにいくつかのテストがあります。

 >>> ob = X(5)
 >>> ob.y
 11
 >>> ob.x = 10
 >>> ob.y
 11
于 2012-08-20T12:57:06.490 に答える
1

結果を に保存し、selfオプションの引数を使用して、計算する必要があるかどうかを確認してみませんか?

何かのようなもの:

def foo(self, *args):
    if args:
        self.c = 0
        for value in args:
            self.c += value

    # In case `self.c` is not set yet, then use default of `0`
    return getattr(self, 'c', 0)

引数を指定して呼び出すfooと、すべての引数が追加されて保存されます。引数なしで呼び出すと、最後に保存された値が返されます。

于 2012-08-20T12:50:33.880 に答える