missing positional arguemnts , creating stack [duplicate] - python

I have some code like:
class Pump:
def __init__(self):
print("init")
def getPumps(self):
pass
p = Pump.getPumps()
print(p)
But I get an error like:
Traceback (most recent call last):
File "C:\Users\Dom\Desktop\test\test.py", line 7, in <module>
p = Pump.getPumps()
TypeError: getPumps() missing 1 required positional argument: 'self'
Why doesn't __init__ seem to be called, and what does this exception mean? My understanding is that self is passed to the constructor and methods automatically. What am I doing wrong here?

To use the class, first create an instance, like so:
p = Pump()
p.getPumps()
A full example:
>>> class TestClass:
... def __init__(self):
... print("in init")
... def testFunc(self):
... print("in Test Func")
...
>>> testInstance = TestClass()
in init
>>> testInstance.testFunc()
in Test Func

You need to initialize it first:
p = Pump().getPumps()

Works and is simpler than every other solution I see here :
Pump().getPumps()
This is great if you don't need to reuse a class instance. Tested on Python 3.7.3.

The self keyword in Python is analogous to this keyword in C++ / Java / C#.
In Python 2 it is done implicitly by the compiler (yes Python does compilation internally).
It's just that in Python 3 you need to mention it explicitly in the constructor and member functions. example:
class Pump():
# member variable
# account_holder
# balance_amount
# constructor
def __init__(self,ah,bal):
self.account_holder = ah
self.balance_amount = bal
def getPumps(self):
print("The details of your account are:"+self.account_number + self.balance_amount)
# object = class(*passing values to constructor*)
p = Pump("Tahir",12000)
p.getPumps()

Adding a #classmethod decorator to the method allows for calling it like Pump.getPumps().
A class method receives the class as the implicit first argument, just like an instance method receives the instance.
class Pump:
def __init__(self):
print("init")
#classmethod
def getPumps(cls):
pass

You can also get this error by prematurely taking PyCharm's advice to annotate a method #staticmethod. Remove the annotation.

If skipping parentheses for the object declaration (typo), then exactly this error occurs.
# WRONG! will result in TypeError: getPumps() missing 1 required positional argument: 'self'
p = Pump
p.getPumps()
Do not forget the parentheses for the Pump object
# CORRECT!
p = Pump()
p.getPumps()

I got the same error below:
TypeError: test() missing 1 required positional argument: 'self'
When an instance method had self, then I called it directly by class name as shown below:
class Person:
def test(self): # <- With "self"
print("Test")
Person.test() # Here
And, when a static method had self, then I called it by object or directly by class name as shown below:
class Person:
#staticmethod
def test(self): # <- With "self"
print("Test")
obj = Person()
obj.test() # Here
# Or
Person.test() # Here
So, I called the instance method with object as shown below:
class Person:
def test(self): # <- With "self"
print("Test")
obj = Person()
obj.test() # Here
And, I removed self from the static method as shown below:
class Person:
#staticmethod
def test(): # <- "self" removed
print("Test")
obj = Person()
obj.test() # Here
# Or
Person.test() # Here
Then, the error was solved:
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.

Related

why can't I call this python function? [duplicate]

I have some code like:
class Pump:
def __init__(self):
print("init")
def getPumps(self):
pass
p = Pump.getPumps()
print(p)
But I get an error like:
Traceback (most recent call last):
File "C:\Users\Dom\Desktop\test\test.py", line 7, in <module>
p = Pump.getPumps()
TypeError: getPumps() missing 1 required positional argument: 'self'
Why doesn't __init__ seem to be called, and what does this exception mean? My understanding is that self is passed to the constructor and methods automatically. What am I doing wrong here?
To use the class, first create an instance, like so:
p = Pump()
p.getPumps()
A full example:
>>> class TestClass:
... def __init__(self):
... print("in init")
... def testFunc(self):
... print("in Test Func")
...
>>> testInstance = TestClass()
in init
>>> testInstance.testFunc()
in Test Func
You need to initialize it first:
p = Pump().getPumps()
Works and is simpler than every other solution I see here :
Pump().getPumps()
This is great if you don't need to reuse a class instance. Tested on Python 3.7.3.
The self keyword in Python is analogous to this keyword in C++ / Java / C#.
In Python 2 it is done implicitly by the compiler (yes Python does compilation internally).
It's just that in Python 3 you need to mention it explicitly in the constructor and member functions. example:
class Pump():
# member variable
# account_holder
# balance_amount
# constructor
def __init__(self,ah,bal):
self.account_holder = ah
self.balance_amount = bal
def getPumps(self):
print("The details of your account are:"+self.account_number + self.balance_amount)
# object = class(*passing values to constructor*)
p = Pump("Tahir",12000)
p.getPumps()
Adding a #classmethod decorator to the method allows for calling it like Pump.getPumps().
A class method receives the class as the implicit first argument, just like an instance method receives the instance.
class Pump:
def __init__(self):
print("init")
#classmethod
def getPumps(cls):
pass
You can also get this error by prematurely taking PyCharm's advice to annotate a method #staticmethod. Remove the annotation.
If skipping parentheses for the object declaration (typo), then exactly this error occurs.
# WRONG! will result in TypeError: getPumps() missing 1 required positional argument: 'self'
p = Pump
p.getPumps()
Do not forget the parentheses for the Pump object
# CORRECT!
p = Pump()
p.getPumps()
I got the same error below:
TypeError: test() missing 1 required positional argument: 'self'
When an instance method had self, then I called it directly by class name as shown below:
class Person:
def test(self): # <- With "self"
print("Test")
Person.test() # Here
And, when a static method had self, then I called it by object or directly by class name as shown below:
class Person:
#staticmethod
def test(self): # <- With "self"
print("Test")
obj = Person()
obj.test() # Here
# Or
Person.test() # Here
So, I called the instance method with object as shown below:
class Person:
def test(self): # <- With "self"
print("Test")
obj = Person()
obj.test() # Here
And, I removed self from the static method as shown below:
class Person:
#staticmethod
def test(): # <- "self" removed
print("Test")
obj = Person()
obj.test() # Here
# Or
Person.test() # Here
Then, the error was solved:
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.

How to use python's getattr feature on a method of a class? [duplicate]

If I have a class ...
class MyClass:
def method(arg):
print(arg)
... which I use to create an object ...
my_object = MyClass()
... on which I call method("foo") like so ...
>>> my_object.method("foo")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: method() takes exactly 1 positional argument (2 given)
... why does Python tell me I gave it two arguments, when I only gave one?
In Python, this:
my_object.method("foo")
... is syntactic sugar, which the interpreter translates behind the scenes into:
MyClass.method(my_object, "foo")
... which, as you can see, does indeed have two arguments - it's just that the first one is implicit, from the point of view of the caller.
This is because most methods do some work with the object they're called on, so there needs to be some way for that object to be referred to inside the method. By convention, this first argument is called self inside the method definition:
class MyNewClass:
def method(self, arg):
print(self)
print(arg)
If you call method("foo") on an instance of MyNewClass, it works as expected:
>>> my_new_object = MyNewClass()
>>> my_new_object.method("foo")
<__main__.MyNewClass object at 0x29045d0>
foo
Occasionally (but not often), you really don't care about the object that your method is bound to, and in that circumstance, you can decorate the method with the builtin staticmethod() function to say so:
class MyOtherClass:
#staticmethod
def method(arg):
print(arg)
... in which case you don't need to add a self argument to the method definition, and it still works:
>>> my_other_object = MyOtherClass()
>>> my_other_object.method("foo")
foo
In simple words
In Python you should add self as the first parameter to all defined methods in classes:
class MyClass:
def method(self, arg):
print(arg)
Then you can use your method according to your intuition:
>>> my_object = MyClass()
>>> my_object.method("foo")
foo
For a better understanding, you can also read the answers to this question: What is the purpose of self?
Something else to consider when this type of error is encountered:
I was running into this error message and found this post helpful. Turns out in my case I had overridden an __init__() where there was object inheritance.
The inherited example is rather long, so I'll skip to a more simple example that doesn't use inheritance:
class MyBadInitClass:
def ___init__(self, name):
self.name = name
def name_foo(self, arg):
print(self)
print(arg)
print("My name is", self.name)
class MyNewClass:
def new_foo(self, arg):
print(self)
print(arg)
my_new_object = MyNewClass()
my_new_object.new_foo("NewFoo")
my_bad_init_object = MyBadInitClass(name="Test Name")
my_bad_init_object.name_foo("name foo")
Result is:
<__main__.MyNewClass object at 0x033C48D0>
NewFoo
Traceback (most recent call last):
File "C:/Users/Orange/PycharmProjects/Chapter9/bad_init_example.py", line 41, in <module>
my_bad_init_object = MyBadInitClass(name="Test Name")
TypeError: object() takes no parameters
PyCharm didn't catch this typo. Nor did Notepad++ (other editors/IDE's might).
Granted, this is a "takes no parameters" TypeError, it isn't much different than "got two" when expecting one, in terms of object initialization in Python.
Addressing the topic: An overloading initializer will be used if syntactically correct, but if not it will be ignored and the built-in used instead. The object won't expect/handle this and the error is thrown.
In the case of the sytax error: The fix is simple, just edit the custom init statement:
def __init__(self, name):
self.name = name
Newcomer to Python, I had this issue when I was using the Python's ** feature in a wrong way. Trying to call this definition from somewhere:
def create_properties_frame(self, parent, **kwargs):
using a call without a double star was causing the problem:
self.create_properties_frame(frame, kw_gsp)
TypeError: create_properties_frame() takes 2 positional arguments but 3 were given
The solution is to add ** to the argument:
self.create_properties_frame(frame, **kw_gsp)
As mentioned in other answers - when you use an instance method you need to pass self as the first argument - this is the source of the error.
With addition to that,it is important to understand that only instance methods take self as the first argument in order to refer to the instance.
In case the method is Static you don't pass self, but a cls argument instead (or class_).
Please see an example below.
class City:
country = "USA" # This is a class level attribute which will be shared across all instances (and not created PER instance)
def __init__(self, name, location, population):
self.name = name
self.location = location
self.population = population
# This is an instance method which takes self as the first argument to refer to the instance
def print_population(self, some_nice_sentence_prefix):
print(some_nice_sentence_prefix +" In " +self.name + " lives " +self.population + " people!")
# This is a static (class) method which is marked with the #classmethod attribute
# All class methods must take a class argument as first param. The convention is to name is "cls" but class_ is also ok
#classmethod
def change_country(cls, new_country):
cls.country = new_country
Some tests just to make things more clear:
# Populate objects
city1 = City("New York", "East", "18,804,000")
city2 = City("Los Angeles", "West", "10,118,800")
#1) Use the instance method: No need to pass "self" - it is passed as the city1 instance
city1.print_population("Did You Know?") # Prints: Did You Know? In New York lives 18,804,000 people!
#2.A) Use the static method in the object
city2.change_country("Canada")
#2.B) Will be reflected in all objects
print("city1.country=",city1.country) # Prints Canada
print("city2.country=",city2.country) # Prints Canada
It occurs when you don't specify the no of parameters the __init__() or any other method looking for.
For example:
class Dog:
def __init__(self):
print("IN INIT METHOD")
def __unicode__(self,):
print("IN UNICODE METHOD")
def __str__(self):
print("IN STR METHOD")
obj = Dog("JIMMY", 1, 2, 3, "WOOF")
When you run the above programme, it gives you an error like that:
TypeError: __init__() takes 1 positional argument but 6 were given
How we can get rid of this thing?
Just pass the parameters, what __init__() method looking for
class Dog:
def __init__(self, dogname, dob_d, dob_m, dob_y, dogSpeakText):
self.name_of_dog = dogname
self.date_of_birth = dob_d
self.month_of_birth = dob_m
self.year_of_birth = dob_y
self.sound_it_make = dogSpeakText
def __unicode__(self, ):
print("IN UNICODE METHOD")
def __str__(self):
print("IN STR METHOD")
obj = Dog("JIMMY", 1, 2, 3, "WOOF")
print(id(obj))
If you want to call method without creating object, you can change method to static method.
class MyClass:
#staticmethod
def method(arg):
print(arg)
MyClass.method("i am a static method")
I get this error when I'm sleep-deprived, and create a class using def instead of class:
def MyClass():
def __init__(self, x):
self.x = x
a = MyClass(3)
-> TypeError: MyClass() takes 0 positional arguments but 1 was given
You should actually create a class:
class accum:
def __init__(self):
self.acc = 0
def accumulator(self, var2add, end):
if not end:
self.acc+=var2add
return self.acc
In my case, I forgot to add the ()
I was calling the method like this
obj = className.myMethod
But it should be is like this
obj = className.myMethod()

Using getattr to call a function in a separate class

I may be trying to do something that is outside of the realm of possibility here, but I figured I would ask first before abandoning hope. So here it goes...
I have 2 classes, A and B. Each class has an arbitrary number of functions. Class B will be instantiated somewhere in Class A and Class A will utilize one of Class B functions via that instantiation. A function in Class B will need to refer to one or more of Class A's functions using it's current instantiation data of Class A.
Class A
#!/usr/bin/python
from classB import classB
class classA(object):
def Apple(self):
print("Inside Apple")
b = classB()
b.Banana()
b.bar()
def foo(self):
print("foo inside apple")
a = classA()
a.Apple()
Class B:
#!/usr/bin/python
import inspect
class classB(object):
def Banana(self):
print("Inside banana")
def bar(self):
print("bar inside banana")
'''
The following lines just show I can get the names of the
calling class and methods.
'''
stack = inspect.stack()
the_class = stack[1][0].f_locals["self"].__class__
the_method = stack[1][0].f_code.co_name
print("Caller Class: {}".format(the_class))
print("Caller Method: {}".format(the_method))
function_name = 'foo'
if hasattr(the_class, function_name):
print("Class {} has method {}".format(the_class,
function_name))
getattr(the_class, function_name)()
I get the following error:
getattr(the_class, function_name)()
TypeError: unbound method foo() must be called with classA instance as first argument (got nothing instead)
Thanks!
As the error suggests, you must build an object of classA (i.e. the_class) before calling getattr on it.
objA = the_class()
But taking a step back, why don't you just pass class A to class B while initializing it?
b = classB(self)
That will allow you to access the exact method of class A that you need.
Else, if method 'foo' in class A is supposed to be a static method, make it so by using #staticmethod decorator.

TypeError: updateCourses() missing 1 required positional argument: 'self' [duplicate]

I have some code like:
class Pump:
def __init__(self):
print("init")
def getPumps(self):
pass
p = Pump.getPumps()
print(p)
But I get an error like:
Traceback (most recent call last):
File "C:\Users\Dom\Desktop\test\test.py", line 7, in <module>
p = Pump.getPumps()
TypeError: getPumps() missing 1 required positional argument: 'self'
Why doesn't __init__ seem to be called, and what does this exception mean? My understanding is that self is passed to the constructor and methods automatically. What am I doing wrong here?
To use the class, first create an instance, like so:
p = Pump()
p.getPumps()
A full example:
>>> class TestClass:
... def __init__(self):
... print("in init")
... def testFunc(self):
... print("in Test Func")
...
>>> testInstance = TestClass()
in init
>>> testInstance.testFunc()
in Test Func
You need to initialize it first:
p = Pump().getPumps()
Works and is simpler than every other solution I see here :
Pump().getPumps()
This is great if you don't need to reuse a class instance. Tested on Python 3.7.3.
Adding a #classmethod decorator to the method allows for calling it like Pump.getPumps().
A class method receives the class as the implicit first argument, just like an instance method receives the instance.
class Pump:
def __init__(self):
print("init")
#classmethod
def getPumps(cls):
pass
The self keyword in Python is analogous to this keyword in C++ / Java / C#.
In Python 2 it is done implicitly by the compiler (yes Python does compilation internally).
It's just that in Python 3 you need to mention it explicitly in the constructor and member functions. example:
class Pump():
# member variable
# account_holder
# balance_amount
# constructor
def __init__(self,ah,bal):
self.account_holder = ah
self.balance_amount = bal
def getPumps(self):
print("The details of your account are:"+self.account_number + self.balance_amount)
# object = class(*passing values to constructor*)
p = Pump("Tahir",12000)
p.getPumps()
You can also get this error by prematurely taking PyCharm's advice to annotate a method #staticmethod. Remove the annotation.
If skipping parentheses for the object declaration (typo), then exactly this error occurs.
# WRONG! will result in TypeError: getPumps() missing 1 required positional argument: 'self'
p = Pump
p.getPumps()
Do not forget the parentheses for the Pump object
# CORRECT!
p = Pump()
p.getPumps()
I got the same error below:
TypeError: test() missing 1 required positional argument: 'self'
When an instance method had self, then I called it directly by class name as shown below:
class Person:
def test(self): # <- With "self"
print("Test")
Person.test() # Here
And, when a static method had self, then I called it by object or directly by class name as shown below:
class Person:
#staticmethod
def test(self): # <- With "self"
print("Test")
obj = Person()
obj.test() # Here
# Or
Person.test() # Here
So, I called the instance method with object as shown below:
class Person:
def test(self): # <- With "self"
print("Test")
obj = Person()
obj.test() # Here
And, I removed self from the static method as shown below:
class Person:
#staticmethod
def test(): # <- "self" removed
print("Test")
obj = Person()
obj.test() # Here
# Or
Person.test() # Here
Then, the error was solved:
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.

Is there a python construct that is a dummy function?

Is there a python construct that corresponds to a function taking no argument, doing nothing and returning nothing ? Something similar to object None but that would be a function instead of an object ?
The context
I want to define a class where the constructor gets a function as an argument and references it to a class attribute. Upon instanciation, the user decides whether he/she wants that function to be an actual function which he/she defines him/herself or leave the default which is to call a dummy function which does nothing.
Here is what I have now :
def sayHello():
print("hello world !")
def doNothing():
pass
class myClass:
def __init__(self, myFunc):
self.doIt = myFunc
myInstance = myClass(sayHello)
myInstance.doIt()
myInstance = myClass(doNothing) # Works but requires defining function doNothing()
myInstance.doIt()
#myInstance = myClass(None) # Returns error "'NoneType' object is not callable"
myInstance.doIt()
How about lambdas?
myInstance = myClass(lambda:None)
Sure you can pass is as default to your __init__ function:
class myClass:
def __init__(self, myFunc = lambda:None):
self.doIt = myFunc
This should work:
class myClass:
def __init__(self, myFunc = lambda : None):
self.doIt = myFunc
myInstance = myClass()
I used the following:
a=lambda:None
a()
print a()
The latter line prints None.
This worked for me:
def none(function=True):
if function==True:
return None
else:
function()

Categories

Resources