How do i create a derived class with certain constructors? (python) - python

This is my class:
class Player(object):
def __init__(self, playernum):
self.playernum = playernum
def play_turn(self, board):
"""This method is passed an instance of ConnectFour.
It should examine the board (using methods on the ConnectFour class...
assume you have it) and eventually call board.play_turn and return"""
pass
So far I understand that if I do:
class Human(Player):
It will make Human() a derived class of Player.
What I would like to do is have a constructor playernum inside this class. Then take the overridden play_turn and print a player number(ie. playernum)...I just want to know how this would be implemented... do I repeat
def play_turn(self,board):
inside the Human class or do I simply put
class Human(Player):
play_turn
and inside the
play_turn(self,board):
"put"
print playernum
I'm kind of new to derivations of classes and the logic behind it. Any input will be highly appreciated. Thanks.

You're correct that to override a method from a parent class, you 'repeat' the method inside the derived class. Your code should end up looking something like:
class Human(Player):
def play_turn(self, board):
print self.playernum
If play_turn is meant to contain shared logic for its derived classes, you want to call the parents' method first:
class Human(Player):
def play_turn(self, board):
super(Human, self).play_turn(board)
print self.playernum

Related

Creating class object inside same class in Python

I'm trying to create a class object inside the class itself, something like this:
class Motor:
#other code here
def function(self):
x = Motor()
This works and runs correctly, but if I use inheritance to create another class as a daughter of this one (e.g. Car(Motor)), the Car.function() doesn't work properly because it's creating an object of type Motor, not Car. Is there any other way I could do this?
Thanks!!
You'll want to receive the class to instantiate as an argument to the method, rather than hard-coding the class name.
class Motor:
#classmethod
def function(cls):
x = cls()
...
If this is really something that needs to be an instance method, you can use type(self) instead.
class Motor:
def function(self):
x = type(self)()

Accessing a nested class via "self"?

So, I have a situation as described as follow:
class A(object):
def __init__(self):
pass
def foo(self):
a = self.InnerClass()
a.hooo()
class InnerClass(object):
def hooo(self):
print 'Yeah!'
class DummyA(A):
class InnerClass(A.InnerClass):
def hooo(self):
print 'Yay!'
class Test(object):
x = DummyA()
x.foo()
A is my main class which I want to test. Then there is an inner class whose function hooo() is getting called. I want to override that function in my DummyA class. so, I did that as described in code. It works and the output is 'Yay!'. I have seen in many examples online that outer class always accesses inner class by this syntax. OuterClass.InnerClass but in my case I have used self to access inner class. Is it bad practice? if so, for what reason? Any other way I can test the function hooo?

inheriting python method with a call to super inside the method

I am developing a system, which has a series of single multilevel inheritance hierarachy. one of the methods (applicable to all the classes) has to perform the same thing for most of the classes, which is to pass a list to its parent class.
I know that if one doesn't define a method in one of the inherited classes, its parents' methods are used. But when we use the super method, we need to mention the name of the class being called.
One method I know to achieve this is to redefine the method at every class with class name as argument. Is there any elegant method where I can define it once at the topmost parent, and then override it only when necessary?
The implementation right now looks like this
class a(object):
def __init__(self):
self.myL = list()
print 'hello'
class b(a):
def __init__(self):
super(b,self).__init__()
def resolve(self, passVal):
print passVal
self.myL.append(passVal)
super(b,self).resolve(passVal+1)
class c(b):
def __init__(self):
super(c,self).__init__()
def resolve(self, passVal):
print passVal
self.myL.append(passVal)
super(c,self).resolve(passVal+1)
Instead if I can define resolve in class a, and then all other classes inherit the method from it. I understand a will never be able to use it. but redefining the method seems a lot unnecessary extra work.

Python class inside subclass inheriting from class inside parent class

The title is pretty much self explanatory, but I think this is better explained with an example.
class Dog():
def __init__(self, name):
self.name = name
def get_name(self):
return self.name
def get_color(self):
return body_color()
class personality_1():
def get_happiness(self):
return happiness_with_owner()
def get_sadness(self):
return sadness()
## A lot more personality methods here
class SocialDog(Dog):
# Override regular method
def get_color(self):
return face_color()
# I want to override the personality 1 class but not completely, just one method
class personality_2(>>>How to inherit from personality_1?<<<):
# Now, I would like to override just one method of personality 1:
def get_happiness(self):
return happiness_with_others()
Hopefully the logic is correct. I was trying to use super() with no success. Hopefully I can find a solution without using an explicit call to the parent class.
Any thoughts?
Thanks in advance!
To inherit from the class you specified, according to the code you provided, all that is required is to define the class personality_2 like this:
class SocialDog(Dog):
#...
class personality_2(Dog.personality_1):
#...
Now, as for your problem when trying to use super(), this might be because your base classes of Dog and Dog.personality_1 do not inherit from the python default class object which is required in order to use the super() method. See this answer for details. If that is what you are after, all you need to do is modify your class declarations for Dog and Dog.personality_1 (or whatever they ultimately derive from) to the following:
class Dog(object):
#...
class personality_1(object):
#...
Then you can treat SocialDog.personality_2 just like any other subclass. If you are using python 2, remember when using super() that you need to use the fully qualified name:
super(SocialDog.personality_2, self).super_class_method()
super(SocialDog.personality_2, self).super_class_field
Use the name of the outer class to reach the inner class:
class SocialDog(Dog):
class personality_2(Dog.personality_1):
# ...
That said, this is a very weird thing you're doing, hiding the personality classes inside the dog classes, then using them outside...
If a personality is that tightly coupled to a specific class like Dog or SocialDog, what makes personality_2 think it's safe to mess with the behaviour of personality_1? In fact, the personality methods should probably be Dog or SocialDog methods instead.
Or, if it doesn't really matter which dog gets which personality, why not leave the personality classes up at the module level, where they can be instantiated and inherited like any other class? Your various Dog-derived classes would then take an optional personality argument when created:
class WolfPersonality(DogPersonality):
# ...
class Wolf(Dog):
def __init__(self, personality=None):
if personality is None:
personality = WolfPersonality()
self.personality = personality
# ...
# Later...
wolf = Wolf()
wolf_puppy = Wolf(FriendlyDogPersonality())

Init child with Parent instance

I have a function which return instances of the class Parent:
def generateParent():
do_stuff
return Parent(some_parameters)
Now I want to init a subclass of Parent with the results of a call to generateParent():
class Child(Parent):
def __new__():
return generateParent(some_other_parameters)
The problem is, when I override some methods from Parent in Child and then call them in instances of Child in my program, the original Parent method gets called instead of the new one from Child. Am I doing something wrong here? Am I using the correct design here for my task?
EDIT: I don't have access neither to Parent nor generateParent()
Solution(thanks to #Paul McGuire's answer):
class Child(object):
def __init__(self):
self.obj = generateParent()
def __getattr__(self, attr):
return getattr(self.obj, attr)
Since generateParent is not your code, then instead of inheritance, you might want to use containment and delegation. That is, instead of defining a subclass, define a wrapper class that contains the generated object, forwards method calls to it when needed, but can add new behavior or modified behavior in the wrapper.
In this question, the OP had a similar situation, having a class generated in a libary, but wanting to extend the class and/or modify some behavior of the class. Look at how I added a wrapper class in that question, and you might consider doing something similar here.
Here's one way to do it:
def generateChild(params):
p = generateParent(params)
p.__class__ = Child
return p
class Child(Parent):
# put method overrides etc here
childinstance = generateChild(some_params)
Perhaps you want generateParent to be able to make instances of other classes:
def generateParent(cls=Parent):
do_stuff
return cls(some_parameters)
Now this will make a Child object:
child = generateParent(Child)
Or perhaps you want Parent and all of its derived classes to use common initialization code?
class Parent(object):
def __init__(self):
do_stuff
# init from some_parameters
class Child(Parent):
# blah..
Make your Child object able to copy information from a created Parent object:
class Child(Parent):
def __init__(self):
model_parent = generateParent()
self.a = model_parent.a
self.b = model_parent.b
# etc.

Categories