Multiple inheritance in python "object.__init__() takes no parameter - python

i am working with
inheritence,here i got output for single inheritence but multiple inheritence showing error.so please help me.I don't have any knowledge about mro in python.please give me good advice.
class Player:
def __init__(self,name,country):
self.name=name
self.country=country
def info(self):
return self.name+":"+self.country
class Ipl(Player):
def __init__(self,name,country,team):
Player.__init__(self,name,country)
self.team=team
def info_ipl(self):
return self.info()+"\nIpl team:"+self.team
x=Ipl("Suresh Raina","India","csk")
print(x.info_ipl())
class Carrier:
def ___init__(self,wicket,run):
self.wicket=wicket
self.run=run
def disp(self):
return "Wickets:"+self.wicket+"Runs:"+self.run
class Aauction(Ipl, Carrier):
def __init__(self,wicket,run,name,country,team):
Ipl.__init__(self,name,country,team)
Carrier.__init__(self,wicket,run)
self.Innings=Innings
def stati(self):
return self.info_ipl()+","+self.disp()+"Total Innings:"
x = Aauction(150,2000,"Suresh_Raina","India","kkr")
print(x.stati())
Above code giving following Error:-
Suresh Raina:India
Ipl team:csk
Traceback (most recent call last):
File "C:\Users\Rahul\Desktop\PYTHON\EXP8.py", line 49, in <module>
x = Aauction(150,2000,"Suresh_Raina","India","kkr")
File "C:\Users\Rahul\Desktop\PYTHON\EXP8.py", line 40, in __init__
Carrier.__init__(self,wicket,run)
TypeError: object.__init__() takes no parameters
Thank you.

I think the problem is that your __init__ has three underscores instead of two:
class Carrier:
def ___init__(self,wicket,run):
self.wicket=wicket
self.run=run
def disp(self):
return "Wickets:"+self.wicket+"Runs:"+self.run
should be:
class Carrier:
def __init__(self,wicket,run):
self.wicket=wicket
self.run=run
def disp(self):
return "Wickets:"+self.wicket+"Runs:"+self.run

Related

Calling class method within class error

class String(object):
def __init__(self, text):
self.text = text
def __repr__(self):
return "{}".format(self.text)
def reverse(self):
return self.text[::-1]
def isPalindrome(self):
return (self.reverse(self.text) == self.text)
def main():
string = String(input("Write a String: "))
if(string.isPalindrome()):
print("The string {{}} IS a Palindrome".format(string))
else:
print("The string {{}} is NOT Palindrome".format(string))
I have this classe that represents a String and i want to check is a object is a palindrome by calling the method isPalindrome. But when i call the string.isPalindrome i get this error:
Traceback (most recent call last):
File "palindrome.py", line 23, in <module>
main()
File "palindrome.py", line 17, in main
if(string.isPalindrome()):
File "palindrome.py", line 12, in isPalindrome
return (self.reverse(self.text) == self.text)
TypeError: reverse() takes 1 positional argument but 2 were given
The error comes from this line:
return (self.reverse(self.text) == self.text)
change it for this:
return (self.reverse() == self.text)
self can be really confusing, here is a really good article to understand how it works. Just so you understand, look at reverse() definition:
def reverse(self):
return self.text[::-1]
As you can see, self.text is already assigned. No need to pass it to the function when calling it.

Error with inheritance in python

i'm doing an UNO game using Pygame, i'm doing it with lists of cards and classes of each color, when I tried to test the inheritance for using the color class, I got this error:
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
x=example()
File "C:/Users/Tamara/Desktop/TEC/UNO/UNOclases.py", line 93, in __init__
Red.__init__(self,Redlist)
TypeError: unbound method __init__() must be called with Red instance as first argument (got example instance instead)
Here's the code (don't mind if one of the names is wrong written, I had to translate it from spanish):
class Red:
def setSpecialRedCards(self):
self.__Redlist.append(self.__steal2)
self.__Redlist.append(self.__steal2)
self.__Redlist.append(self.__Reverse)
self.__Redlist.append(self.__Reverse)
self.__Redlist.append(self.__Jump)
self.__Redlist.append(self.__Jump)
def setRedNumers (self, number,counter):
while counter<=9:
if numero!=0:
self.__Redlist.append(number)
self.__Redlist.append(number)
else:
self.__listaRoja.append(number)
number+=1
counter+=1
def getRed(self):
return self.__Redlist
def __init__(self, Redlist=[]):
self.__Redlist=Redlist
self.__number0 = "red 0"
self.__steal2 = "steal2"
self.__Reverse = "Reverse"
self.__jump = "jump"
class example:
def __init__(self, Redlist=[]):
Red.__init__(self,Redlist)
def example2(self):
return Red.__number0
Thank you for your help!
Your class example doesn't inherit from class Red.
Write
class example(Red):
....

How can i write a decorator using a class's __call__ function?

The following is my code. Given any content, it has to append certain HTML tag to the content at the front.
I'm learning to write decorators using call instead of function closures.
class decorate:
def __init__(self, tag=""):
self.tag = tag
def __call__(self, function, *args):
return "<p>{}</p>".format(self.tag, function(*args), self.tag)
#decorate(tag="p")
def get_content(content):
return content
print(get_content("I'm awesome"))
# Error i got.
Traceback (most recent call last):
File "cache.py", line 27, in <module>
#decorate(tag="p")
File "cache.py", line 25, in __call__
return "<p>{}</p>".format(self.tag, function(*args), self.tag)
TypeError: get_content() takes exactly 1 argument (0 given)
Change:
def __call__(self, function, *args):
return "<p>{}</p>".format(self.tag, function(*args), self.tag)
into:
def __call__(self, function):
def wrap(*args):
return "<{}>{}</{}>".format(self.tag, function(*args), self.tag)
return wrap
You may want to look into functools for more refined decoration of wrap, but except for supporting help and the like, this should work.

Decorator to invoke instance method

I have a class A with method do_something(self,a,b,c) and another instance method that validates the input and check permissions named can_do_something(self,a,b,c).
This is a common pattern in my code and I want to write a decorator that accepts a validation function name and perform the test.
def validate_input(validation_fn_name):
def validation_decorator(func):
def validate_input_action(self,*args):
error = getattr(self,validation_fn_name)(*args)
if not error == True:
raise error
else:
return func(*args)
return validate_input_action
return validation_decorator
Invoking the functions as follows
#validate_input('can_do_something')
def do_something(self,a,b,c):
return a + b + c
Problem is that i'm not sure how to maintain self through out the validation function. I've used the validation fn name with getattr so the fn could be ran in the context of the instance but i cannot do that for func(*args).
So what is the proper way to achieve this ?
Thanks.
EDIT
So following #André Laszlo answer I realized that self is just the first argument so there is no need to use getattr at all but just pass on the *args.
def validate_input(validation_fn):
def validation_decorator(func):
def validate_input_action(*args):
error = validation_fn(*args)
if not error == True:
raise error
else:
return func(*args)
return validate_input_action
return validation_decorator
Much more elegant and it also supports static methods as well.
Adding a static method to #André Laszlo example proves the decorator is working :
class Foo(object):
#staticmethod
def validate_baz(a,b,c):
if a > b:
return ValueError('a gt b')
#staticmethod
#validate_input(Foo.validate_baz)
def baz(a,b,c):
print a,b,c
>>> Foo.baz(1,2,3)
1 2 3
>>> Foo.baz(2,1,3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 6, in validate_input_action
ValueError: a gt b
But, when i'm trying to do them same thing in a django model:
from django.db import models
from django.conf import settings
settings.configure()
class Dummy(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=10)
def can_say_name(self):
if name is None:
return Exception('Does not have a name')
#validate_input(can_say_name)
def say_name(self):
print self.name
#staticmethod
def can_create_dummy(name):
if name == 'noname':
return Exception('No name is not a name !')
#staticmethod
#validate_input(Dummy.can_create_dummy)
def create_dummy(name):
return Dummy.objects.create(name=name)
I get the following :
NameError: name 'Dummy' is not defined
So what is the different between a django model and an Object in relation to this issue ?
I think this does what you want:
def validate_input(validation_fn_name):
def validation_decorator(func):
def validate_input_action(self, *args):
error = getattr(self, validation_fn_name)(*args)
if error is not None:
raise error
else:
arglist = [self] + list(args)
return func(*arglist)
return validate_input_action
return validation_decorator
class Foo(object):
def validate_length(self, arg1):
if len(arg1) < 3:
return ValueError('%r is too short' % arg1)
#validate_input('validate_length')
def bar(self, arg1):
print "Arg1 is %r" % arg1
if __name__ == "__main__":
f = Foo()
f.bar('hello')
f.bar('')
Output is:
Arg1 is 'hello'
Traceback (most recent call last):
File "validator.py", line 27, in <module>
f.bar('')
File "validator.py", line 6, in validate_input_action
raise error
ValueError: '' is too short
Updated answer
The error (NameError: name 'Dummy' is not defined) occurs because the Dummy class is not defined yet when the validate_input decorator gets Dummy as an argument. I guess this could have been implemented differently, but for now that's the way Python works. The easiest solution that I see is to stick to using getattr, which will work because it looks up the method at run time.

exec to add a function into a class

So I've looked at similar questions, and I've found some solutions to this, but I can't quite figure out how to do this.
What I'm trying to do is add a method to a class from a string. I can do this with the setattr() method, but that won't let me use self as an attribute in the extra method. Here's an example: (and I apologize for the variable names, I always use yolo when I'm mocking up an idea)
class what:
def __init__(self):
s = 'def yolo(self):\n\tself.extra = "Hello"\n\tprint self.extra'
exec(s)
setattr(self,"yolo",yolo)
what().yolo()
returns this:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: yolo() takes exactly 1 argument (0 given)
and if s = 'def yolo():\n\tself.extra = "Hello"\n\tprint self.extra'
then I get this result:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 2, in yolo
NameError: global name 'self' is not defined
This essentially means that I cannot dynamically create methods for classes, which I know is bad practice and unpythonic, because the methods would be unable to access the variables that the rest of the class has access to.
I appreciate any help.
You have to bind your function to the class instance to turn it into a method. It can be done by wrapping it in types.MethodType:
import types
class what:
def __init__(self):
s = 'def yolo(self):\n\tself.extra = "Hello"\n\tprint self.extra'
exec(s)
self.yolo = types.MethodType(yolo, self)
what().yolo()
On a side note, why do you even need exec in this case? You can just as well write
import types
class what:
def __init__(self):
def yolo(self):
self.extra = "Hello"
print self.extra
self.yolo = types.MethodType(yolo, self)
what().yolo()
Edit: for the sake of completeness, one might prefer a solution through the descriptor protocol:
class what:
def __init__(self):
def yolo(self):
self.extra = "Hello"
print self.extra
self.yolo = yolo.__get__(self)
what().yolo()
Another way, seems more elegant to me:
class what:
pass
ld = {}
exec("""
def yolo(self):
self.extra = "Hello"
print(self.extra)
""", None, ld)
# print('locals got: {}'.format(ld))
for name, value in ld.items():
setattr(what, name, value)
what().yolo()

Categories