Reputation: 153
I'm reading this book called Master Object Oriented programming Python by Steven Lott.
I came across this code:
class Card:
def __init__( self, rank, suit ):
self.suit= suit
self.rank= rank
self.hard, self.soft = self._points()
class NumberCard( Card ):
def _points( self ):
return int(self.rank), int(self.rank)
class AceCard( Card ):
def _points( self ):
return 1, 11
class FaceCard( Card ):
def _points( self ):
return 10, 10
I'm not able to understand how can self._points()
in Card be legal expression.
I run the code in compiler too it stats the following error Instance of Card has No points member
Full Code I have kept it as gist here
Upvotes: 2
Views: 74
Reputation: 31584
From your error: it is just a pylint issue, if you do not do something like c = Card(1, 2)
, it will be ok.
The code in fact is correct.
It intends you will call it like n = NumberCard(1, 2)
, then __init__
will be used by its subclass, and subclass has the function _points
.
In fact, for other language, usually we need to define a _points
function in parent class. Then, subclass could override the function in parent class. But python
is not so strict, so you could do without define _points
function in parent class, but then you will just able to new a object for its subclass not parent class.
To sum all, what you need to google is function override
of OOP.
Upvotes: 1
Reputation: 106598
The __init__()
function of the base class, Card
, tries to access the member function _points()
, when it has none. That its subclasses all have such a member function doesn't help the base class from getting this member function. You simply can't instantiate Card
directly because it really is an abstract class.
You should use the abc
module to declare Card
as an abstract class, and Card._points
as an abstract method, and instantiate child classes instead:
from abc import ABC, abstractmethod
class Card(ABC):
def __init__( self, rank, suit ):
self.suit= suit
self.rank= rank
self.hard, self.soft = self._points()
@abstractmethod
def _points(self):
return None, None
class NumberCard( Card ):
def _points( self ):
return int(self.rank), int(self.rank)
class AceCard( Card ):
def _points( self ):
return 1, 11
class FaceCard( Card ):
def _points( self ):
return 10, 10
a=AceCard(1,2)
print(a.hard, a.soft)
Upvotes: 1