Why is my Python abc setup giving errors?

beavoid
beavoid used Ask the Experts™
on
Hi
My PyCharm is giving surprising red-underlining on import abc, object, and from abc import
Up til now, my chess engine has been working on a player class, but I'd like it to be an abstract base class. I am re-designing it
Must I do any special entries in the Project Settings panel? my code below doesn't seem to be a problem,



My abc is :
import abc

class ChessPlayer(object):
    __metaclass__= abc.ABCMeta

    @abc.abstractmethod
    def get_white_move(self, white_moves):
        """white player chooses the best move for this turn"""
        return

    @abc.abstractmethod
    def get_black_move(self, black_moves):
        """black player chooses the best move for this turn"""
        return

Open in new window

My derivative class is:
import abc
from abc_base import ChessPlayer:


class RandomPlayer(Object):
# ToBeDone, once setup is correct

Open in new window


Thanks
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Save your base code as abc_base.py:
import abc

class ChessPlayer(object):
    __metaclass__= abc.ABCMeta

    @abc.abstractmethod
    def get_white_move(self, white_moves):
        """white player chooses the best move for this turn"""
        return

    @abc.abstractmethod
    def get_black_move(self, black_moves):
        """black player chooses the best move for this turn"""
        return

Open in new window


Now, save the derived in whatever file, say a.py:
#!python3
import abc
from abc_base import ChessPlayer


class RandomPlayer(ChessPlayer):
    """ToBeDone, once setup is correct"""

    def __repr__(self):
        return "my RandomPlayer instance"

p = RandomPlayer()
print(p)

Open in new window


I did use the Python 3 (3.6.2 in my case). Now some remarks...

In the from abc_base import ChessPlayer: you want to remove the final colon (syntax error).

In the class RandomPlayer(Object): you want to replace Object by your base class that is ChessPlayer. There is no base class named Object (unless you defined it elsewhere).

In your base class (in abc_base.py), you want to remove the object. There was a time (Python versions) when object was used as a base class explicitly (similarly to other languages), but it should not be used now.

When running the script (in Windows in my case), you will observe the following:
D:\___Python\beavoid\ee29104217>py a.py
my RandomPlayer instance

Open in new window

beavoidSelf Employed

Author

Commented:
Thanks a lot
I've done what you suggested, and there are some errors that I don't understand.

I did the name change for abc_base.py:

My RandomPlayer.py does appropriate implementations of the methods:
import abc, random
from abc_base import ChessPlayer


class RandomPlayer(ChessPlayer):
    def __init__(self):
        pass

    def get_white_move(self, white_moves):
            len =white_moves.len()
            print('get_white_move()')
            random_move_index = random.randint(0,len)
            white_move = white_moves[random_move_index]
            return white_move


    def get_black_move(self, black_moves):
        len = black_moves.len()
        print('get_black_move()')
        random_move_index = random.randint(0, len)
        black_move = black_moves[random_move_index]
        return black_move

Open in new window


Why does the instantiation of a randomPlayer fail in the engine class? :
import RandomPlayer


class ChessEngine:
    def __init__(self):

        white_player = RandomPlayer()


print('main')



engine = ChessEngine()

Open in new window



Thanks
You do import RandomPlayer. This is the module stored as RandomPlayer.py file. Inside, there is the class RandomPlayer.

In the __init__, you wrote RandomPlayer(); however, the RandomPlayer name belongs to the imported module. If you want to use the class from inside the module, you have to add .RandomPlayer. So, the call will be RandomPlayer.RandomPlayer(). The first one is for the module, the second (after the dot) is the name of the class.

Alternatively, you can import only the class RandomPlayer from the module RandomPlayer like this:
from RandomPlayer import RandomPlayer

Open in new window

Then the module namespace is not imported, and the RandomPlayer class appears as if defined in your code (merged into your own namespace). Then you can call it as you do (without the module name and the dot).

From another point of view, the module name defines its own name-space (of the same name as the module).

A side note: There is a bug in the __init__. You should use self.white_player instead of white_player. And the self. must be explicitly used everywhere you work with class members (unlike in other languages as C++ or C# or Java). You have more bugs there, but you will "catch them all" :)
beavoidSelf Employed

Author

Commented:
Thanks

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial