I am new to OOP and I am wondering why I need to supply the parameter MainWindow to the final line. If I call outside_func by itself, I don't need a parameter, but when I call it within a class i need to supply the class name for it to work. For example, MainWindow.class_func2() throws an error
class MainWindow():
def __init__(self):
print("in init")
def claas_func(self):
print ("func1")
def class_func2(self):
outside_func()
def outside_func():
print('outside called')
instance = MainWindow()
MainWindow.class_func2(MainWindow)
You should take a look to #staticmethod
class MainWindow():
def __init__(self):
print("in init")
def claas_func(self):
print ("func1")
#staticmethod
def class_func2():
return outside_func()
def outside_func():
print('outside called')
instance = MainWindow()
>> in init
instance.class_func2()
>> outside called
this #staticmethod (which itself it's something really cool called 'decorator') will make the method itself entirely callable without having pass 'self'.
Hope it helps
Try this instead. You have created an instance of MainWindow(). Now you can access its members with that.
class MainWindow():
def __init__(self):
print("in init")
def claas_func(self):
print ("func1")
def class_func2(self):
outside_func()
def outside_func():
print('outside called')
instance = MainWindow()
instance.class_func2()
Also run this and notice it initializes the MainWindow() class 2x. I DO NOT recommend this second approach. It is redundant and not proper. But just so you can kind of see what it is doing.
class MainWindow():
def __init__(self):
print("in init")
def claas_func(self):
print ("func1")
def class_func2(self):
outside_func()
def outside_func():
print('outside called')
instance = MainWindow()
MainWindow().class_func2()
Related
I suppose I'm missing something obvious, but I can't get the name of methods when I'm using decorators. When I run this code, I get the error:
AttributeError: 'str' object has no attribute "__name__"
Could somebody tell me how I can get the name of these decorated method?
Thanks
def Print(*arg, **kwarg):
func, *arguments = arg
print(func.__name__ + "(): {}".format(func=arguments[0]))
class Bob(object):
def __init__(self):
pass
#property
def stuff(self):
return "value from stuff property"
#stuff.setter
def stuff(self, noise):
return noise
class Tester:
def __init__(self):
self.dylan = Bob()
def randomTest(self):
Print(self.dylan.stuff, 1)
if __name__ == "__main__":
whatever = Tester()
whatever.randomTest()
stuff isn't a function or a method; it's a property. The syntax
#property
def stuff(...):
...
creates an instance of the property class using stuff as the argument to property, equivalent to
def stuff(...):
....
stuff = property(stuff)
and instances of property don't have a __name__ attribute, as you've seen.
(It's a little trickier with the setter, since the function and the property have to have the same name. But defining stuff a "second" time doesn't override the existing property named stuff.)
The individual methods are accessed via attributes of the property.
>>> Bob.stuff.fget.__name__
'stuff'
>>> Bob.stuff.fset.__name__
'stuff'
Note another, longer, way to create the same property:
class Bob:
def stuff_getter(self):
...
def stuff_setter(self, noise):
...
stuff = property(stuff_getter, stuff_setter)
del stuff_getter, stuff_setter # Clean up the namespace
def Print(*arg, **kwarg):
func, *arguments = arg
print(func.__name__ + "(): {}".format(func=arguments[0]))
class Bob():
def __init__(self, s):
self.stuff = s
#property
def myStuff(self):
return self.stuff
#myStuff.setter
def setStuff(self, noise):
self.stuff = noise
class Tester:
def __init__(self):
self.dylan = Bob(1)
def randomTest(self):
print(self.dylan.stuff)
if __name__ == "__main__":
whatever = Tester()
whatever.randomTest()
This should work :)
How I can call a function inside class like this code? I tried, but I can not... The idea is: I want update the other function inside de class, than I use this code, without sucess: app=MyApp() app.build.last1.text=time.strftime("%H:%M:%S \n")
How I do it?
(...)
class PL1_detect(Button):
def update(self, dt):
global ModoPisca
global t
global ModoPisca2
global last2
#ModoPisca=0
def tpisca():
conta=0
global estado_PTT1
##clock(self, dt)
app=MyApp()
app.build.last1.text=time.strftime("%H:%M:%S \n")
#(here the problem: HOW I CAN CALL FUNCTION OF CLASS
MYAPP(APP) ????
(...)
class MyApp(App):
def build(self):
layout = FloatLayout(size=(800, 600))
# Make the background gray:
with layout.canvas.before:
Color(.2,.2,.2,1)
self.rect = Rectangle(size=(800,600), pos=layout.pos)
wimg = Image(source='logo.png', pos=(0,180))
last1=Label(text=(" "), pos=(-330, -110), font_size='17sp', bold=0)
return layout
if __name__ == '__main__':
MyApp().run()
You can create object for that class
M=Myapp()
M.build() will help in calling that function.
Try this for your scenario
class A():
def funct1(self):
sample="hi"
class B():
def func2(self):
A.sample="hello"
print A.sample
a=A()
a.funct1()
b=B()
b.func2()
Output:
hello
I want to do something like this:
class worker():
def run(self):
# Do something
class main():
def __init__(self):
worker_obj = worker()
main_obj = main()
main_obj.worker_obj.run()
Is something like this wrong/possible?
You need to attach the attribute to self to make it available to use outside the function. Currently you are creating a function variable and not an instance attribute.
Change your class to below
class worker():
def run(self):
# Do something
class main():
def __init__(self):
self.worker_obj = worker()
main_obj = main()
main_obj.worker_obj.run()
You need to assign worker_obj as an attribute of the instance (self):
class main():
def __init__(self):
self.worker_obj = worker()
Otherwise, you are simply creating a local variable within __init__ that immediately goes out of scope.
I'm trying to make some kind of static inheritance happen.
The code below prints "nope".
I'm not sure how to explain myself but what I want is that
class A uses B's method if it exists.
class A(object):
#staticmethod
def test():
print("nope")
#staticmethod
def test2():
__class__.test()
class B(A):
#staticmethod
def test():
print("It Works")
#staticmethod
def run():
__class__.test2()
if __name__ == "__main__":
B.run()
__class__ as a closure reference was never meant to be used as a reference to the current instance type; it'll always refer to the class you defined a method on (e.g. A for A.test2). It is a internal implementation detail used by the super() function. Don't use it here.
Use #classmethod instead;
class A(object):
#classmethod
def test(cls):
print("nope")
#classmethod
def test2(cls):
cls.test()
class B(A):
#classmethod
def test(cls):
print("It Works")
#classmethod
def run(cls):
cls.test2()
if __name__ == "__main__":
B.run()
I'm tying to create a class that holds a reference to another classes method. I want to be able to call the method. It is basically a way to do callbacks.
My code works until I try to access a class var. When I run the code below, I get the error What am I doing wrong?
Brian
import logging
class yRunMethod(object):
"""
container that allows method to be called when method run is called
"""
def __init__(self, method, *args):
"""
init
"""
self.logger = logging.getLogger('yRunMethod')
self.logger.debug('method <%s> and args <%s>'%(method, args))
self.method = method
self.args = args
def run(self):
"""
runs the method
"""
self.logger.debug('running with <%s> and <%s>'%(self.method,self.args))
#if have args sent to function
if self.args:
self.method.im_func(self.method, *self.args)
else:
self.method.im_func(self.method)
if __name__ == "__main__":
import sys
#create test class
class testClass(object):
"""
test class
"""
def __init__(self):
"""
init
"""
self.var = 'some var'
def doSomthing(self):
"""
"""
print 'do somthing called'
print 'self.var <%s>'%self.var
#test yRunMethod
met1 = testClass().doSomthing
run1 = yRunMethod(met1)
run1.run()
I think you're making this WAY too hard on yourself (which is easy to do ;-). Methods of classes and instances are first-class objects in Python. You can pass them around and call them like anything else. Digging into a method's instance variables is something that should almost never be done. A simple example to accomplish your goal is:
class Wrapper (object):
def __init__(self, meth, *args):
self.meth = meth
self.args = args
def runit(self):
self.meth(*self.args)
class Test (object):
def __init__(self, var):
self.var = var
def sayHello(self):
print "Hello! My name is: %s" % self.var
t = Test('FooBar')
w = Wrapper( t.sayHello )
w.runit()
Why not use this:
self.method(*self.args)
instead of this:
if self.args:
self.method.im_func(self.method, *self.args)
else:
self.method.im_func(self.method)
In your code you were calling self.method.im_func(self.method) - you shouldn't have been passing the method as argument but the object from which that method came. I.e. should have been self.method.im_func(self.method.im_self, *self.args)