This question already has answers here:
Interesting 'takes exactly 1 argument (2 given)' Python error
(6 answers)
Closed 6 years ago.
I get the following error "TypeError: make_pretty() takes exactly 1 argument (2 given)" for the below code snippet. I'm learning python and any help would be helpful...
class test:
def make_pretty(func):
def inner():
print("I got decorated")
func()
return inner
def ordinary():
print("I am ordinary")
pretty1 = test()
pretty = pretty1.make_pretty(pretty1.ordinary)
print(pretty())
I also tried it with decorators, but still face the same error..
class SmartDivide:
def smart_divide(self,func):
def inner(a,b):
print("I am going to divide",a,"and",b)
if b == 0:
print("Whoops! cannot divide")
return
return func(a,b)
return inner
#smart_divide
def divide(self,a,b):
return a/b
dvd = SmartDivide()
print(dvd.divide(2,5))
dvd.divide(2,0)
You may need the self keyword
class test:
def make_pretty(self, func):
def inner():
print("I got decorated")
func()
return inner
def ordinary(self):
print("I am ordinary")
pretty1 = test()
pretty = pretty1.make_pretty(pretty1.ordinary)
print(pretty())
Related
This question already has answers here:
What is the purpose of the `self` parameter? Why is it needed?
(26 answers)
Closed 12 months ago.
The above code works but the second code shows typerror: print(a.factorial(a, 5))TypeError: factorial() takes 2 positional arguments but 3 were given:
class Factorial:
def factorial(self, num):
if num == 0:
return 1
if num ==1:
return 1
else:
return num * self.factorial(self, num-1)
def main():
a = Factorial()
print(Factorial.factorial(Factorial, 5))
main()
The second code is as follows:
class Factorial:
def factorial(self, num):
if num == 0:
return 1
if num ==1:
return 1
else:
return num * self.factorial(self, num-1)
def main():
a = Factorial()
print(a.factorial(a, 5))
main()
self argument is the same as the object on which you call the function. You don't need to provide it again as the first explicit argument - a.factorial(5) will work.
When you call a method on an instance (rather than on the class), the instance is automatically passed as the self argument. You don't pass it yourself.
So this:
Factorial.factorial(a, 5)
is the same as this:
a.factorial(5)
and this:
a.factorial(a, 5)
is the same as this:
Factorial.factorial(a, a, 5) # too many arguments!
Note that your function definition is also confused about the difference between instances and classes. Given that this is an instance method, it should expect self to be an instance of Factorial, not the Factorial class itself:
def factorial(self, num):
if num == 0:
return 1
if num ==1:
return 1
else:
return num * self.factorial(num-1) # no extra "self" arg
Once you make this fix, calling this method as Factorial.factorial(Factorial, 5) will not work, because that's not a valid way to call an instance method (it "works" in your current code because of that self bug that prevents it from working as an actual instance method).
To define it as a class method (where the first argument is the class, not an instance), you'd do:
#classmethod
def factorial(cls, num):
if num == 0:
return 1
if num ==1:
return 1
else:
return num * cls.factorial(num-1)
and then would call it as Factorial.factorial(5).
This question already has an answer here:
What does <function at ...> mean [duplicate]
(1 answer)
Closed 4 years ago.
I want to have a dictionary where a certain key calls a value... that value is a function and I would want that function to execute.
Below is my attempt to do it but all I get is the value of where it is stored in memory.
class Testing:
def __init__(self):
self.method = {'Method1': self.another, 'Method2': self.there}
def launch(self, input):
print(self.method[input])
#staticmethod
def another():
print('This print statement should pop out.')
#staticmethod
def there():
print('This should not appear.')
new = Testing()
new.launch('Method1')
The result that I get from that is:
<function Testing.another at 0x01519540>
Is there a way to do this?
You are missing the actual function call: (notice the added () at the end)
def launch(self, input):
print(self.method[input]())
This question already has answers here:
How to get a function name as a string?
(14 answers)
Closed 4 years ago.
If I want to pass a function func1 as argument in another function, but want to return the function name, what shall I do?
let say
def func1(x):
return x**2
def main_function(func1,x):
.....
return ___(name of func1),value of func1(x)___
which means I want things like:
func_name, result = main_function(func1,2)
print(func_name)
func1
print(result)
4
def func1(x):
return x**2
def main_function(f,x):
print('f name=', f.__name__)
print('f value=', f(x))
main_function(func1, 5)
output is
f name= func1
f value= 25
Try this:
def main_function(f, x):
return f.__name__, f(x)
Just use __name__ to get function name as str.
def main_function(func, x):
# do something else
return func.__name__, func(x)
I have a class file. Let's call it "C1.py". The sample code looks like below.
class C1(object):
def __init__(self):
self.greeting = "Hello, world!"
def M1(ans):
if ans == 1 or ans == 2:
return True
else:
return False
Now, I have another python file in the same folder, which will access the class file shown above.
from trial import C1
def getAns(class1):
while True:
ans = input("Answer: ")
if class1.M1(ans):
return ans
break
sample = C1()
print sample.greeting
ans = getAns(sample)
print ans
When I run those files, sample.greeting prints fine. Everything is fine until when the execution reaches the line "ans = getAns(C1)", which gives the error "M1() takes exactly 1 argument (2 given)".
So, where in the code should I change so that I can call that method successfully?
Note here that the above code is only the abstraction of my whole program to highlight my problem. It sounds stupid with just the code above alone. So, please, please bear with that for me.
M1 is currently defined as a method of C1, as such it needs to have an additional self argument which would be the instance of the class. I.e
class C1(object):
def __init__(self):
self.greeting = "Hello, world!"
def M1(self, ans):
if ans == 1 or ans == 2:
return True
else:
return False
In other languages such as C++ or Java the presence of self (or this) is implicit, but in python it's explicit.
alternatively if you don't want or need M1 to access C1's state you could make M1 static via #staticmethod i.e.
class C1(object):
def __init__(self):
self.greeting = "Hello, world!"
#staticmethod
def M1(ans):
if ans == 1 or ans == 2:
return True
else:
return False
so I got around to messing with classes and decorators but I can't seem to get past this error: TypeError: make_sandwich() takes exactly 2 arguments (1 given)
I tried doing all of it outside of a class and it works. Any ideas on how to make this work inside my sandwich maker?
class SandwichMaker:
def __init__(self):
self.sandwich = []
self.bread = "========"
self.bacon = " ~~~~~~ "
self.olives = " oooooo "
def make_sandwich(self, insides):
def add_bread():
self.sandwich.insert(0, self.bread)
insides()
self.sandwich.append(self.bread)
return add_bread
def add_bacon(self):
return self.bacon
def add_olives(self):
return self.olives
#make_sandwich
def print_sandwich(self):
for i in range(len(self.sandwich)):
print self.sandwich[i]
my_sandwich = SandwichMaker()
my_sandwich.add_olives()
my_sandwich.add_bacon()
my_sandwich.print_sandwich()
edit: hey, so I fixed it thanks to the answers. If anyone wants to grab a fully working, nonsense sandwich printer, below is the final version:
def make_sandwich(insides):
def add_bread(self):
bread = "========"
print bread
insides(self)
print bread
return add_bread
class SandwichMaker:
def __init__(self):
self.sandwich = []
self.bacon = " ~~~~~~ "
self.olives = " oooooo "
def add_bacon(self):
self.sandwich.append(self.bacon)
def add_olives(self):
self.sandwich.append(self.olives)
#make_sandwich
def print_sandwich(self):
for i in range(len(self.sandwich)):
print self.sandwich[i]
my_sandwich = SandwichMaker()
my_sandwich.add_bacon()
my_sandwich.add_olives()
my_sandwich.add_bacon()
my_sandwich.add_bacon()
my_sandwich.print_sandwich()
#make_sandwich
def print_sandwich(self):
…
When you use the decorator syntax like that, then only the function is passed to the decorator. So make_sandwich receives only a single argument. But as the error says, it takes exactly two.
So you need to change make_sandwich to take only the function reference, not the implicit self which is the sandwich instance.
As soon as you do that, you will run into two more issues: The function that is returned from make_sandwich does not take any argument, so when you call the decorated print_sandwich, the implicit self is passed but the function does not take any argument. So you need to change the inner function to take the implcit self. The last issue is then that the decorated function will be called without the implicit self. So you need to call it as insides(self) to fix that.
The decorator should then look like this:
def make_sandwich(insides):
def add_bread(self):
self.sandwich.insert(0, self.bread)
insides(self)
self.sandwich.append(self.bread)
return add_bread
Take a look at the answers in: Python class method decorator w/ self arguments? and Python decorators in classes
If I understand what you're after, I would suggest the following (summarized) approach:
class SandwichMaker:
def make_sandwich(func):
def inner(self):
print("do before")
func(self)
print("do after")
return inner
#make_sandwich
def print_sandwich(self):
print("foo")
s = SandwichMaker()
s.print_sandwich()