Due to some circumstances I can only pass the argument to one function within a class.
Example:
class win1():
def __init__(self):
self.diction = dict()
self.x = self.wanted_touse()
#is it possible to make it here? If yes, it will be good to be like this
# self.X = X or self.y = Y (is this even possible without passing an argument in it?)
def fun(self, X,Y):
self.x = X
self.y = Y
def wanted_touse(self):
#I wanted to use X and Y here while at the same time I cannot pass the argument to this function because of some circumstances.
#Here with some functions to make the dictionary for self.x example for x in enumerate(self.x)
self.diction[something] = something
I would like to learn to see whether is it possible to use a variable within a function in win1 into want_touse function.
Define your attribute in the __init__(), and then modify it in your fun() function, like this:
class win1():
def __init__(self):
self.x = None
def fun(self, X,Y):
self.x = X
def wanted_touse(self):
pass
#do whatever you want with self.x here, so long as you've run your fun() function and changed self.x as you intended.
This example is just using a single variable. You can apply this to additional variables as needed.
Related
I am trying to get values from kindle() and process them in bundle() and call these two functions in main, but i get the error: NameError: name 'x' is not defined at the bundle()'s first line, while x is declared globally.
class Program:
x = 0
y = 0
def kindle(self):
x = 2
y = 3
return x, y
def bundle(self):
z = x+ y
print(z)
def main():
p = Program()
p.kindle()
p.bundle()
if __name__ == "__main__":
main()
Ah, a discussion of classes. So, the x and y you defined "globally" are not really global, they are class objects and accessed from the class. For example,
class thing:
x = 10
def func(self):
print(thing.x)
Notice that the "x" is attached to the class "thing". Hence, "x" is not global. In general, anything inside of a class is accessed through the class and is not apart of the outside space.
Of course, one of the MAIN benefits of using classes is that all the functions and variables share a common namespace. An instance of this namespace is referred to as "self" and is passed around automatically to all class functions. Hence, doing "thing.x" is completely unnecessary (and requires that I know the name of the class). Instead we can do:
class thing:
x = 10
def func(self):
print(self.x)
We can go further of course. If I can access self at all times in a class, then if I attached to the self, other functions will be able to see that attachment automatically. Lets try:
class Program:
x = 0 #Default value if we don't overwrite.
y = 0 #Default value if we don't overwrite.
def kindle(self):
self.x = 2 #Overwrote the default.
self.y = 3 #Overwrote the default.
#No need to return anything. Self already has x and y attached.
def bundle(self):
z = self.x + self.y
print(z)
#z is not attached to self, hence z is only available in this function.
def main():
p = Program() #Create an instance of the Program class.
p.kindle() #Overwrite the default x and y values for just this instance.
p.bundle() #Add the values and print.
if __name__ == "__main__":
main()
For this code when I change x to k using change() and then call self.co it does not return the updated value of self.x. How do I fix this kind of problem generally (this is a basic example)?
class scope:
tag=1
def __init__(self,h,x):
self.h = h
self.x = x
self.co=(self.x,self.h)
def change(self,k):
self.x=k
You did not change the self.co attribute. You are assigning to self.co only when initialization of scope occurs, that is, when you call scope().Also Python doesn't keep references like pointers in c so changing one would not change the other.
To prove this run this code:
class scope:
tag=1
def __init__(self,h,x):
self.h = h
self.x = x
self.co=(self.x,self.h)
def change(self,k):
self.x=k
s = scope(2,3)
print(s.co)
print("id of self.x before change:", id(s.x)) #11161896
print("id of self.co's x before change:", id(s.co[0])) #11161896
s.change(6)
print(s.co)
print("id of self.x after change:", id(s.x)) #11161824
print("id of self.co's x after change:", id(s.co[0])) #11161896
The id are the memory location of the object, and you can see it first starts out the same, but then when you change self.x the memory location in the co doesn't change
You have to update self.co in your change(). If you want a dynamically changing co without manually updating it, write a method to retrieve co.
Option 1:
class scope:
tag=1
def __init__(self,h,x):
self.h = h
self.x = x
self.co=(self.x,self.h)
def change(self,k):
self.x=k
self.co = (self.x,self.h)
Option 2:
class scope:
tag=1
def __init__(self,h,x):
self.h = h
self.x = x
def change(self,k):
self.x=k
def co(self):
return (self.x,self.h)
s = scope(2,3)
print(s.co()) #(3,2)
s.change(6)
print(s.co()) #(6,2)
You can add to method 2 with a decorator #property to not make it a function call but at this point, I have no idea what your requirements are.
You should define self.co as property of class via using #property decorator. For example:
class Scope:
tag=1
def __init__(self,h,x):
self.h = h
self.x = x
def change(self,k):
self.x=k
#property
def co(self):
return (self.x, self.h)
Sample Run:
>>> s = Scope(3, 5)
>>> s.co # initial value
(5, 3)
>>> s.change(45) # update value of `self.x`
>>> s.co # updated value
(45, 3)
Here, on calling self.co will return the dynamic value of (self.x, self.y) each time is called.
Issue with your code: In your code, when you initialized self.co = (self.x,self.h) in your __init__, a new tuple self.co was created holding the value of (self.x, self.y) (which was not holding the reference to these variable). Hence, when you updated self.x, it was not updated in your tuple object.
You have to call function with the name it is defined
Second you can use global keyword also
For example
value = 10
Update()
def Update():
global value
value = 11
I have a little question about python 3.
I want to create a class, which is using a function from within of that class. Just like:
class Plus:
def __init__(self, x, y):
self.x = x
self.y = y
self.test()
def test(self):
return self.x + self.y
now I am doing something like
a = Plus(5,6)
print(a)
and python is giving me
<__main__.Plus object at 0x000000000295F748>
and not 11 as I want it. I know that I can get 11 by
a = Plus(5, 6).test()
print(a)
but that's not what I want. I want to call the class and getting the result without adding .test() to it.
Can you help me?
I would go for:
class Plus:
def __init__(self, x, y):
self.x = x
self.y = y
self.test()
def test(self):
res = self.x + self.y
self.__repr__ = lambda:str(res)
return res
>>> Plus(5,5)
10
>>> a = Plus(5,5)
>>> a
10
>>> a.test()
10
This way you are not recomputing the sum each time you call print, its updated when you call the test method.
You'd need to define a __str__ method for your Plus class:
class Plus:
def __init__(self, x, y):
self.x = x
self.y = y
def test(self):
return self.x + self.y
def __str__(self):
return str(self.test())
now I am doing something like
a = Plus(5,6)
print(a)
and python is giving me
<__main__.Plus object at 0x000000000295F748>
and not 11 as I want it. I know that I can get 11 by
a = Plus(5, 6).test()
print(a)
but that's not what I want. I want to call the class and getting the result without adding .test() to it.
I am not sure what do you mean by 'and not 11 as I want it'. If you want Plus(5, 6) to actually return 11 (int instance), you should make Plus a function that returns the sum. Alternatively you can override __new__ method and hook upon object creation -- but this is a bad idea.
What are you trying to achieve?
I doubt, that by 'and not 11 as I want it' you want something special to be printed (formatted, represented). If so, override __str__ or __unicode__ or __repr__ method.
Edit:
ignore this answer, it is a comment on a misinterpretation of the question
This is just wrong.
when you instantiate an object, you'd expect to get a reference to that object.
if you just want a global function returning a number, why even bother to make a class with an init?
in python you shouldn't want static class's like in C# for encapsulation. instead name the module something, and use that for encapsulation.
Example code:
>>> class MyClass(object):
def __init__(self, x, y):
self.x = x
self.y = y
def power(self):
print(self.x**self.y)
def divide(self):
print(self.x/self.y)
>>> foo = MyClass(2, 3)
>>> bar = MyClass(4, 7)
>>>
>>> foo.power()
8
>>> bar.divide()
0.5714285714285714
Whenever I used classes in Python previously, I just ran the method for each instance separately (see above). I was just wondering If there was a way to run the same method for all the instances of that class at once, because it could get a bit annoying, if you have 20 or so instances. I'm thinking of something like this:
>>> allinstances.power()
8
16384
Is there a way of doing this?
class MyClass(object):
instancelist = []
def __init__(self, x, y):
self.x = x
self.y = y
MyClass.instancelist.append(self)
def power(self):
print(self.x ** self.y)
def divide(self):
print(self.x / self.y)
foo = MyClass(2, 3)
bar = MyClass(4, 7)
[instance.power() for instance in MyClass.instancelist]
will output:
8
16384
This way you do not need any global variables or placeholders that are stored outside of the class definition.
Not usually. You could make your class be capable of that, however:
GLOBAL_MYCLASS_LIST = []
class MyClass(object):
def __init__(self, x, y):
GLOBAL_MYCLASS_LIST.append(self)
self.x = x
self.y = y
def power(self):
print(self.x**self.y)
def divide(self):
print(self.x/self.y)
a = MyClass(2, 3)
b = MyClass(4, 7)
all_powers = [i.power() for i in GLOBAL_MYCLASS_LIST]
Of course, you could also do that without baking it into the class, which is probably cleaner for most cases where you might have different sets of MyClasses:
myclass_list = []
class MyClass(object):
def __init__(self, x, y):
self.x = x
self.y = y
def power(self):
print(self.x**self.y)
def divide(self):
print(self.x/self.y)
myclass_list.append(MyClass(2, 3))
myclass_list.append(MyClass(4, 7))
all_powers = [i.power() for i in myclass_list]
From your question, I believe you would want a bit of dynamism too. Something like below could help:
I have added a function called printBoth() for demonstration.
Note: Python 2.x code below
class MyClass(object):
def __init__(self, x, y):
self.x = x
self.y = y
def power(self):
print "power",self.x**self.y
def divide(self):
print "divide", self.x/self.y
def printBoth(self):
print "x: ", self.x
print "y: ", self.y
class Test:
def __init__(self, items):
self.items = items
def __getattr__(self, key):
def fn():
return [getattr(x,key)() for x in self.items]
return fn
foo = MyClass(2, 3)
bar = MyClass(4, 7)
t = Test([foo,bar])
t.power()
t.divide()
t.printBoth()
Output:
power 8
power 16384
divide 0
divide 0
x: 2
y: 3
x: 4
y: 7
Note: The code can break on many occasions, you neeed to perform additional checks in real implementation.
The important part is here:
def __getattr__(self, key):
def fn():
return [getattr(x,key)() for x in self.items]
return fn
The above function is invoked upon any function call on the Test instance. What is returned is function that takes no arguments. The function runs over all the instances, and invokes the same function on every item on self.items (which is the list of all the instances you want to invoke your function on). The results are returned as a list.
Sure. Put the instances in a list as you create them, then iterate over the list and call the method on each instance. Also, you should change your methods to return rather than print their results, as this is much more flexible. That way you can store the results in a list, write them to a file, do further calculations with them, or print them.
instances = [MyClass(2, 3), MyClass(4, 7)]
results = [x.power() for x in instances]
Just use a loop:
foo = MyClass(2, 3)
bar = MyClass(4, 7)
for i in [foo, bar]:
i.power()
If you are not sure that all instances will have the method, use a hasattr check:
for i in list_of_instances:
if hasattr(i, 'power'):
i.power()
I think all answers are valid, depending on the use case. I would argue that if this class is used in seperated parts of your app/program you wouldn't want to depend on the GLOBAL_MYCLASS_LIST declared some where before (as #amber suggested). You would want to be sure this variable exists and declare it as a Class Variable and have the compute_all as a Class method or even as a static method with #staticmethod decorator (which I think is less relevant to the specific use case.
Again, I would stress that this is a very specific use case, and not very common. so you should think about your design before doing that and not using the more straight pythonic ways offered in other answers.
I would also like to refer you to this nice video of a Pycon lecture about classes in python which does a nice job of explaining this (The decks are here.)
I would like to call a method from a class on something created by another method in the class. How would I do this?
For example, I've just created a class called call me, and would like to use the result of the subtract method in the add method.
class call_me(object):
def __init__(self, x, y):
self.x = 5
self.y = 10
def subtract(self):
difference = self.y - self.x
return difference
def add(self.subtract,second_number):
# code to add the difference returned by subtract to the second number.
How would I add a second number to the difference returned by subtract? Is there a way I could pass difference to add?
def add(self, second_number):
difference = self.substract()
return difference + second_number