I want to have a class and be able to change an object value and have it flow through to methods and objects created in the class. In the below example I am trying have the new value 3
flow through but I keep getting the original value 2
. Am I doing it wrong?
class fun:
g=2
def a(c=g):
return c
z=g
fun.g = 3
fun.a()
fun.z
I have searched for __init__
functions but I don't see how they can help here. I tried created a new class making is the same as the fun
class. That didn't work either.
as otheres mentioned, just want to point out that def a(c=g):
the g
has been replaced with 2 during class creation.
so after
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})
As you can see 'a': <function __main__.fun.a(c=2)>,
In python, methods and functions have their default values calculated and stored when the method or function is declared.
You can defer that calculation by doing it inside the method at runtime:
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
The problem is that parameters of a function is evaluated at compile time not runtime! Because in compile time the value of g
is 2 and in your function you return that value, it's always going to be 2.
As a point, you call a()
function on the class itself, so it's first parameter is not going to be filled with a reference to an instance. Story changes when you try to call it from instance of that class.
For demonstration take a look at this :
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())
They both have same value.
The solution is to put g
equal to None for default value and then inside the function check whether that value is passed or not:
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())
Not sure quite what you mean by reinitialize, __init__
occurs only on creation. If you create a new fun
object it will be initialized in the same way with the same value.
$ 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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.