【问题标题】:How to reinitialize a method within python class with updated object value如何使用更新的对象值重新初始化python类中的方法
【发布时间】:2021-09-28 03:15:53
【问题描述】:

我想要一个类,并且能够改变一个对象的值,并让它流向类中创建的方法和对象。在下面的示例中,我尝试让新值 3 流过,但我不断获得原始值 2。我做错了吗?

class fun:
  g=2
  def a(c=g):
    return c
  z=g

fun.g = 3
fun.a()
fun.z

我已经搜索了__init__ 函数,但我看不到它们在这里有什么帮助。我尝试创建一个与fun 相同的新类。那也没用。

【问题讨论】:

  • 您在这里面临几个不同的问题,但听起来您正在寻找getterssetters。在 python 中,@property 装饰器用于此目的。
  • 可以更改现有函数的默认参数值,但不建议这样做。
  • 感谢您的信息和阅读材料,非常有帮助。我必须以完全不同的方式接近

标签: python python-3.x class oop


【解决方案1】:

在python中,方法和函数的默认值是在声明方法或函数时计算并存储的。

您可以通过在运行时在方法内部执行该计算来推迟该计算:

class fun:
  g=2
  def a(c=None):  # None is used here as a sentinal value
    if c is None:
        c=fun.g
    return c
  z=g

【讨论】:

  • 不过,这不会更新 fun.z 的值。我认为这个想法是能够根据fun.g 的值更新几项内容,只需进行一次更改。
  • z = property(lambda self: self.g),也许吧。
  • 好吧,省略z。请改用g
  • @chepner 你是对的,实际上只是关于如何通过一次更改进行多次更新的速记示例......不幸的是,我似乎无法找到一种方法来制作代码简单/可读。本质上,一个类中的大量方法/对象需要继承这个值,这个值会随着使用而改变
【解决方案2】:

问题是函数的参数是在编译时而不是运行时计算的!因为在编译时g 的值是 2,而在你的函数中你返回这个值,它总是 2。

首先,您在类本身上调用a() 函数,因此它的第一个参数不会填充对实例的引用。当您尝试从该类的实例中调用它时,故事会发生变化。

为了演示看看这个:

from datetime import datetime
from time import sleep

class C:
    def fn(self, date=datetime.now()):
        return date

obj = C()
print(obj.fn())
sleep(2)
print(obj.fn())

它们都具有相同的值。

解决方案是将g 设为None 作为默认值,然后在函数内部检查该值是否通过:

from datetime import datetime
from time import sleep

class C:
    def fn(self, date=None):
        if date:
            return date
        return datetime.now()

obj = C()
print(obj.fn())
sleep(2)
print(obj.fn())

【讨论】:

    【解决方案3】:

    正如其他人提到的,只是想指出 def a(c=g): g 在类创建过程中已被替换为 2。

    之后

    fun.g = 3
    
    print(fun.__dict__)
    
    mappingproxy({'__module__': '__main__',
                  'g': 3,
                  'a': <function __main__.fun.a(c=2)>,
                  'z': 2,
                  '__dict__': <attribute '__dict__' of 'fun' objects>,
                  '__weakref__': <attribute '__weakref__' of 'fun' objects>,
                  '__doc__': None})
    

    如你所见'a': &lt;function __main__.fun.a(c=2)&gt;,

    【讨论】:

      【解决方案4】:

      不太清楚你所说的重新初始化是什么意思,__init__ 仅在创建时发生。如果您创建一个新的fun 对象,它将以相同的方式使用相同的值进行初始化。

      $ cat fun.py
      
      class fun(object):
      
          def __init__(self):
              self.g = 2
      
          def a(self, c=None):
              if c is None:
                  c = self.g
              return c
      
      
      first = fun()
      second = fun()
      
      first.g = 3
      
      print(first.g)
      print(first.a())
      print(second.g)
      print(second.a())
      
      $ python3 fun.py
      3
      3
      2
      2
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-13
        • 2017-04-07
        • 1970-01-01
        • 2016-06-29
        • 2016-02-09
        • 2019-10-14
        相关资源
        最近更新 更多