Method of an object in Python - python

I was just pulling off a toy example for myself, but it is not working and I cannot make it work. Does anybody know why this is not working and how to make it work:
class A(object):
#def __init__():
#pass
def do1():
print("foo")
def do2():
print("Hello")
Al = A
Al.do1()
TypeError: unbound method do1() must be called with A instance as first argument (got nothing instead)

In your code variable A1 it's reference to your class not instance, create instance of your class
Al = A()
and run your method
Al.do1()

You need to call your class to crate a correct instance and pass the self keyword to enclosing function to provides a handle back to the instance to be processed :
class A(object):
#def __init__():
#pass
def do1(self):
print("foo")
def do2():
print("Hello")
Al = A()
Al.do1()
Note that without passing the self to your function after calling it you will get a TypeError.
TypeError: do1() takes 0 positional arguments but 1 was given
Or as #Padraic Cunningham mentioned in comment you can use staticmethod as a decorator to wrap your function which makes python doesn't pass the first default argument (self) to it.
class A(object):
#def __init__():
#pass
#staticmethod
def do1():
print("foo")
def do2():
print("Hello")
Al = A()
Al.do1()

Related

Get the object that a function was called from in python

If I have a class that contains a method, and I call that method from an instance, how do I get the specific instance it was called from?
e.g. I have a class:
class foo:
def __init__(self):
pass
def do_something(self):
bar()
I also have a function:
def bar():
print()
If i make an object, e.g. obj = foo(), and then i call obj.do_something(), How would i get obj from inside my bar() function?
Using the inspect module, you can get the caller frame and access its local variables, in particular the self argument representing the instance:
import inspect
def bar():
caller = inspect.stack()[1].frame
localvars = caller.f_locals
self = localvars['self']

Python 3 : Inheritance and the assignment of "self"

Why does this script require "self" as an argument to mssg() in line 3? PyCharm flags "self" in line 3 as, expected type "Another", got "Main" instead. This warning makes sense to me (although the code works). When "self" is omitted, Python throws an error:
TypeError: mssg() missing 1 required positional argument: 'self'
class Main():
def __init__(self):
print(Another.mssg(self))
class Another():
def __init__(self):
pass
def mssg(self):
return "Hello World"
_foo = Main()
Using your guidance, here are three different ways to prevent the TypeError:
class Main():
def __init__(self):
print(Another.mssg('asdasdsa'))
print(Another().mssg())
print(_bar.mssg())
class Another():
def __init__(self):
pass
def mssg(self):
return "Hello World"
_bar = Another()
_foo = Main()
If you use Another.mssg(self), then your are calling a class method, that is why self is taken as a parameter and you need to use exactly one argument to call the function. Try print(Another.mssg('asdasdsa')) and you will see that it works.
If your intention was using mssg(self) as an instance method, then you should call it using print(Another().mssg()), so you create your instance and then you call its method.

TypeError: generatecode() takes 0 positional arguments but 1 was given

I have the code below:
from tkinter import *
class Window(Frame):
def __init__(self, master = None):
Frame.__init__(self, master)
self.master = master
self.init_window()
def init_window(self):
self.master.title("COD:WWII Codes")
self.pack(fill=BOTH, expand=1)
codeButton = Button(
self,
text="Generate Code",
command=self.generatecode
)
codeButton.place(x=0, y=0)
def generatecode(self):
f = open("C:/Programs/codes.txt", "r")
t.insert(1.0. f.red())
root = Tk()
root.geometry("400x300")
app = Window(root)
root.mainloop()
Then, I got the error below:
TypeError: generatecode() takes 0 positional arguments but 1 was given
So, how can I solve the error?
When you call a method on a class (such as generatecode() in this case), Python automatically passes self as the first argument to the function. So when you call self.my_func(), it's more like calling MyClass.my_func(self).
So when Python tells you "generatecode() takes 0 positional arguments but 1 was given", it's telling you that your method is set up to take no arguments, but the self argument is still being passed when the method is called, so in fact it is receiving one argument.
Adding self to your method definition should resolve the problem.
def generatecode(self):
pass # Do stuff here
Alternatively, you can make the method static, in which case Python will not pass self as the first argument:
#staticmethod
def generatecode():
pass # Do stuff here
I got the same error:
TypeError: test() takes 0 positional arguments but 1 was given
When defining an instance method without self and I called it as shown below:
class Person:
# ↓↓ Without "self"
def test():
print("Test")
obj = Person()
obj.test() # Here
So, I put self to the instance method and called it:
class Person:
# ↓↓ Put "self"
def test(self):
print("Test")
obj = Person()
obj.test() # Here
Then, the error was solved:
Test
In addition, even if defining an instance method with self, we cannot call it directly by class name as shown below:
class Person:
# Here
def test(self):
print("Test")
Person.test() # Cannot call it directly by class name
Then, the error below occurs:
TypeError: test() missing 1 required positional argument: 'self'
But, if defining an instance method without self, we can call it directly by class name as shown below:
class Person:
# ↓↓ Without "self"
def test():
print("Test")
Person.test() # Can call it directly by class name
Then, we can get the result below without any errors:
Test
In detail, I explain about instance method in my answer for What is an "instance method" in Python? and also explain about #staticmethod and #classmethod in my answer for #classmethod vs #staticmethod in Python.
The most upvoted answer does solve this issue,
And just in case anyone is doing this inside of a jupyternotebook. You must restart the kernel of the jupyternotebook in order for changes to update in the notebook

Python's descriptor "__get__" was not called as I expected, reason?

I was trying python's descriptor of get, to see if it's called.
I've got the following:
"""This is the help document"""
class c1(object):
"""This is my __doc__"""
def __get__(s,inst,owner):
print "__get__"
def __init__(s):
print "__init__"
s.name='abc'
class d(object):
def __init__(s):
s.c=c1()
d1=d()
d1.c
print d1.c.name
I expect that it will call get function. But it fact the output is
__init__
abc
Why my "get" function was not called by instance owner of "d1"?
Thanks!
Descriptors must be bound to a class, not an instance.
class d(object):
c = c1()

how to start or call a function from a different class in python?

hey guys need to know as of how to start a method in a classA from class B
have
classA(object):
def __init__(self):
#this is where the ClassB method'' def multiplyPeople() ''should be called or started.
classB(object):
def multiplyPeople(self):
its giving an error
TypeError: unbound method multiplyPeople() must be called
with classB instance as first argument (got nothing instead)
know this is something basic, but am trying to figure out what exactly is supposed to be done and where am I getting lost.
I have called it as
classA(object):
def__init__(self):
self.PeopleVariable=classB.multiplyPeople()
It depends on how you want the function to work. Do you just want to use the class as a placeholder? Then you can use a so called static method for which you do not need to instantiate an object.
Or you can use a regular method and use it on a created object (notice that there you have access to self)
class A():
def __init__(self):
b = B()
b.non_static()
B.multiplyPeople()
class B():
#staticmethod
def multiplyPeople():
print "this was called"
def non_static(self):
print self, " was called"
if __name__ == "__main__":
a = A()
output:
<__main__.B instance at 0x7f3d2ab5d710> was called
this was called

Categories