python:如何在不更改参数的情况下调用函数?

python:如何在不更改参数的情况下调用函数?,python,class,function,arguments,Python,Class,Function,Arguments,如果我有一个函数: def foo(self, a, b): c = a + b return c def bar(self): z = self.foo(2, 4) return (z) 如何在不更改函数中的c的情况下调用foo?假设我在另一个函数中调用foo: def foo(self, a, b): c = a + b return c def bar(self): z = self.foo(2, 4) return (

如果我有一个函数:

def foo(self, a, b):
    c = a + b
    return c
def bar(self):
    z = self.foo(2, 4)
    return (z)
如何在不更改函数中的c的情况下调用foo?假设我在另一个函数中调用foo:

def foo(self, a, b):
    c = a + b
    return c
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.
基本上,我试图在类中保留一个帐户,以便其他类可以访问相同的帐户;只是一个简单的平衡,加上和减去钱


谢谢。

c
存储为类变量或全局变量,并重写函数以返回旧值

e、 g

注意:您必须处理何时更新
存储的\u c
以及任何并发问题


更新:WRT glglgl的注释,因方法重载而更新。

c
存储为类变量或全局变量,并重写函数以返回旧值

e、 g

注意:您必须处理何时更新
存储的\u c
以及任何并发问题


更新:WRT glglglgl的注释,针对方法重载进行了更新。

为什么不将结果存储在
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
,它将添加所有参数并存储它。如果在没有参数的情况下调用,它将返回最后存储的值。

为什么不将结果存储在
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
,它将添加所有参数并存储它。如果调用时没有参数,它将返回最后存储的值。

c
是函数的本地值,而不是静态值。这意味着每次函数退出时,
c
都会被垃圾回收。为什么不存储第一次计算的
c
的值呢?这似乎是显而易见的答案。

c
是函数的局部函数,而不是静态的。这意味着每次函数退出时,
c
都会被垃圾回收。为什么不存储第一次计算的
c
的值呢?这似乎是显而易见的答案。

您想要的似乎是缓存属性。您可以制作一个实现描述符的装饰器,作为将来使用的通用对象:

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

看起来您想要的是缓存属性。您可以制作一个实现描述符的装饰器,作为将来使用的通用对象:

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

您需要一些构造来保存最后的结果。例如,你可以对函数做一些包装

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

您将得到相同的结果。

您需要一些构造来保存最后的结果。例如,你可以对函数做一些包装

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

你也会得到同样的答案。

我接受了罗汉提供的答案,并得出以下结论。这似乎是可行的,尽管可能有更好的/首选的方法来实现这一点

下面的代码允许我跨多个类和方法跟踪帐户余额

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)

我采纳了罗汉提供的答案,并得出以下结论。这似乎是可行的,尽管可能有更好的/首选的方法来实现这一点

下面的代码允许我跨多个类和方法跟踪帐户余额

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)

这完全没有道理
c
是一个局部变量,它不会在函数调用中持久存在。根据您的问题以及您对其他人答案的回答,我建议您学习一些python;也许这有帮助,或者有人能解释为什么我在这个问题上投了反对票?我不明白这是个什么样的问题。我不想浪费人们的时间,但我经常发现这些文档非常理论化,而且示例相对较少。所以,当我陷入困境时,我会去这里。我如何改进我的问题?看起来你的反对票“太偏离轨道了”:-)不要害羞-你的问题是理解“结构化”和“面向对象”问题之间区别的关键-从某种意义上说,你想要的东西只能用对象来正确完成。只是想让舒尔明白发生了什么。这完全没有意义
c
是一个局部变量,它不会在函数调用中持久存在。根据您的问题以及您对其他人答案的回答,我建议您学习一些python;也许这有帮助,或者有人能解释为什么我在这个问题上投了反对票?我不明白这是个什么样的问题。我不想浪费人们的时间,但我经常发现这些文档非常理论化,而且示例相对较少。所以,当我陷入困境时,我会去这里。我如何改进我的问题?看起来你的反对票“太离谱了”:-)不要害羞-你的问题是理解的关键