I'm trying to set a variable and be able to change and store that variable using set and gets. The current output is:
0
0
I'm trying to get it to be:
0
2
Can some one help me understand how to change a value and then use it later in python? Kind of like a toggle?
class Spammer:
def __init__(self, spam = 0):
self._spam = spam
# getter method
def get_spam(self):
return self._spam
# setter method
def set_spam(self, x):
if x == 1:
return self._spam+1
if x== 0:
return self._spam
spammer=Spammer()
print (spammer.get_spam())
spammer.set_spam(1)
print(spammer.get_spam())
There is an #property decorator builtin so you could do the following:
class Spammer:
def __init__(self, spam = 0):
self._spam = spam
#property
def spam(self):
return self._spam
#spam.setter
def spam(self, new_spam):
self._spam = new_spam
Related
Is it possible to make a dot function that is var.function() that changes var? I realise that i can do:
class Myclass:
def function(x):
return 2
Myclass.function(1):
But i want to change it like the default python function.
def function(x):
return(3)
x=1
x.function()
print(x)
and it returns
>>> 3
class Myclass:
def __init__(self, num):
self.num = num
def function(self):
self.num += 1
def __str__(self):
return str(self.num)
x = Myclass(3)
x.function()
print(x)
This is weird usage. I suggest you to create custom class to do that, try using #property inside it if you don't want to call function in code.
Trying to get a work around for getting access to a class method in another class while being inside a class. Code below will probably explain my goal.
class Access(object):
def __init__(self):
pass
def select(self, value):
Store.keep(value)
class Store(object):
def __init__(self):
self.store_value = 0
def keep(self, value):
self.store_value = value
x = Access()
y = Store()
x.select(10)
y.store_value
##Want the output of 10
I don't see any way to do what you want without Access having a reference to a Store object.
The closest thing you can do is
class Access(object):
def __init__(self):
pass
def select(self, value):
Store.keep(value)
class Store(object):
#classmethod
def keep(cls, value):
cls.store_value = value
x = Access()
y = Store()
x.select(10)
print y.store_value #will print 10
#but
z = Store()
print z.store_value #will print 10 too
Where store_value is shared by all instances of Store.
You could pass an instance to select also and use Store.keep(inst, value):
class Access(object):
def __init__(self):
pass
def select(self, inst, value):
Store.keep(inst, value)
class Store(object):
def __init__(self):
self.store_value = 0
def keep(self, value):
self.store_value = value
x = Access()
y = Store()
x.select(y, 10)
print(y.store_value)
10
I have the following Class and the corresponding method.
#!/usr/bin/env python
class Foo:
def __init__(self, x):
self.x = x
def bar(self):
bar_out = self.x + 5
return bar_out
def qux(self):
qux_out = bar_out + 3
return qux_out
def main():
"""docstring for main"""
f = Foo(5)
main_bar_out = f.bar()
print main_bar_out
#main_qux_out = f.qux()
#print main_qux_out
if __name__ == '__main__':
main()
What I want to do here is to make the method a=qux takes the value from bar, process it and return a value. So that the final output of main_qux_out is 13. How can I do this correctly?
Note that here I want qux() to take the value automatically from bar(), without passing any parameter.
Update
Thanks for #thefourtheye, for the response. I have further questions.
Let say if I want to have bar() to return two or more values (this can be string, string, list or dict), how can I call it from qux(). I tried this but failed.
#!/usr/bin/env python
class Foo:
def __init__(self, x):
self.x = x
def bar(self):
self.bar1_out = self.x + 5
self.bar2_out = self.x + 1
return (self.bar1_out,self.bar2_out)
def qux(self):
self.qux_out1 = self.bar1_out() + 3
self.qux_out2 = self.bar2_out() + 6
return ( self.qux_out1, self.qux_out2)
def main():
"""docstring for main"""
f = Foo(5)
mbr_out1, mbr_out2 = f.bar()
print mbr_out1, "\t", mbr_out2
mqx_out1, mqx_out2 = f.qux()
print mqx_out1, "\t", mqx_out2
if __name__ == '__main__':
main()
This should print:
10 6
13 12
You cannot access a local variable defined in one function, from another function. But you can invoke the bar function and use the return value like this
def qux(self):
return self.bar() + 3
If you want to decide which value to use (bar or the value passed as parameter) dynamically, then you can do something like this
def qux(self, myvalue = None):
if myvalue is not None:
return myvalue + 3
else:
return self.bar() + 3
If you don't pass any value to qux, myvalue will be default take None as its value. Inside the function, we check if it is not None, then we use the value as it it, otherwise we call self.bar() and use that value.
If you are planning to return two values from bar, then you can unpack them like this
def qux(self, myvalue = None):
first, second = myvalue or self.bar()
return first + 3, second + 6
Here myvalue or self.bar() makes sure that we take self.bar() if myvalue is None.
Note: If you are planning to do this way, then you need pass two values for myvalue as well, like this
self.qux((1, 2))
methods inside of a class can only access variables of that class or variables defined inside the method. What you ought to do is either make bar a variable of the class (instead of being part of the method)
def bar(self):
self.bar_out = self.x + 5
return self.bar_out
or call bar() and use the output in the calculation
def qux(self):
qux_out = self.bar() + 3
I have two classes. a and b.
In one of class a's methods, I created an object of class b. One of class b attributes takes a function. So say I gave it a random function but does this function of class b have access to class a's attribute? even though I didn't pass it in directly as a parameter?
class b:
def __init__(self):
self.attribute_function = None
class a:
def __init__(self):
self.temp = 10
self.counter = 0
def temp(self):
obj = b()
obj.attribute_function = lambda self: self.counter < self.temp
return obj.attribute_function()
if __name__ == "__main__":
#pass
obj = a()
print obj.temp()
In the above example, I tried to provide a really basic example, but if you run it, it doesn't work...
Revised Code, class a should look like this:
class a:
def __init__(self):
self.temp = 10
self.counter = 0
def temp(self):
obj = b()
obj.attribute_function = lambda args: self.counter < self.temp
return obj.attribute_function(1) # i added this 1 to fill in arg
This works:
class b:
def __init__(self):
self.attribute_function = None
class a:
def __init__(self):
self._temp = 10
self.counter = 0
def temp(self):
obj = b()
obj.attribute_function = lambda self=self: self.counter < self._temp
return obj.attribute_function()
if __name__ == "__main__":
obj = a()
print obj.temp()
On problem you had is self.temp = 10 which shadowed your method temp().
Another problem: lambda self: self.counter < self._temp. Your lambda function was expecting an argument. But omitting self is not a good idea lambda : self.counter < self._temp, because if you call obj.attribute_function() somewhere where self is not available or has changed - it will not find self or use another self. self=self fixes that.
But generally such magic is an anti-pattern. Tell us what are your trying to achieve, and there should be a better way to do what you want. Otherwise this kind of code will ensure many headaches.
I think this is a better solution (called strategy pattern):
class B:
def __init__(self, a):
self.a = a
def temp(self):
return self.a.temp()
class A:
def __init__(self):
self._temp = 10
self.counter = 0
def temp(self):
return self.counter < self._temp
if __name__ == "__main__":
obj = B(A())
print obj.temp()
Your example does not work because you have a name collision at temp
You have assigned temp to be both a method:
def temp(self):
and an attribute:
self.temp = 10
I want a variable to do more than just be set when I set it.
and the interface to be as clean as possible.
short: what I'd want:
# have class with a variable that I can access:
print myInstance.var
42
# change the variable
myInstance.var = 23
# have the change kick off another method:
self.var was changed: 23!!
hmm.. so what I can do: Use the variable and a setter method:
class Test:
def __init__(self):
self.var = 1
print( 'self.var is: ' + str(self.var) )
def setVar(self, value):
self.var = value
print( 'self.var changed: ' + str(self.var) )
t = Test()
self.var is: 1
# so I have t.var at hand:
print t.var
1
# and change it this way
t.setVar(5)
self.var changed: 5
But then i have 2 different things to work with..
Ok I could make a method to interact with the var:
class Test:
def __init__(self):
self.var = 1
print( 'self.var is: ' + str(self.var) )
def method(self, value=None):
if value == None:
return self.var
self.var = value
print( 'self.var changed: ' + str(self.var) )
t = Test()
self.var is: 1
# to get the value then:
print t.method()
1
# to set it:
t.method(4)
self.var changed: 4
# and verifiy:
print t.method()
4
This is nice already. I've seen it in different post on other languages. but I dunno. Is there a be better solution in python?!?
Maybe I'm paranoid but but to me it'd just feel nicer to just do t.var = 5 and have something kicked off too.
I think you want python Properties. Check this out. Something like:
class Test:
def __init__(self):
self._var = 1
#property
def var(self):
return self._var
#var.setter
def var(self, value):
# add stuff here that you want to happen on var assignment
self._var = value
You can use a property. Note that if the setter method is expensive, it's better to use a method. People expect attribute access to be fast.
class Foo(object):
def __init__(self):
self._var = None
#property
def var(self):
return self._var
#var.setter
def var(self, whatever):
self._var = whatever
do_whatever()
x = Foo()
print x.var # prints None
x.var = 2 # sets x.var and does whatever