creating class objects inside methods

horos11 horos11 at gmail.com
Sun Oct 4 07:12:37 CEST 2009


> >>> a
>
> <__main__.Myclass instance at 0x95cd3ec>>>> b
>
> <__main__.Myclass instance at 0x95cd5ac>
>
> What's the problem?

Like I said, the code was a sample of what I was trying to do, not the
entire thing.. I just wanted to see if the metaphor was kosher.

It sounds to me from your answer that this is unexpected behavior, so
I'll go ahead and post the whole thing. My guess is that it is a
python bug..

Run it (a simple puzzle game solved by breadth first search), and the
first time state() is called inside the method, it calls __init__.
Second time, and therafter, it calls __call__. I've highlighted where
the code fails by putting a pdb.set_trace().

Anyways, I've got a workaround (simply pass in any new objects needed
from the caller), but it is truly annoying that python is either
misleading or broken in this way.

Attached find code, does not work vs. 2.6..


Ed

----

from collections import deque
import copy
import pdb

class state:

    def default_board():

        return [
              [ 1, 'x', 'x', 0 ],
              [ 2, 2,  3,  4 ],
              [ 5, 6,  6,  7 ],
              [ 5, 6,  6,  7 ],
              [ 8, 9, 10, 10 ],
              [ 0, 'x', 'x', 0 ]
            ]

    def default_types():

        return {
                1  : [ 0, 0 ],
                2  : [ 0, 0, 0, 1 ],
                3  : [ 0, 0 ],
                4  : [ 0, 0 ],
                5  : [ 0, 0, 1, 0 ],
                6  : [ 0, 0, 1, 0, 0, 1, 1, 1 ],
                7  : [ 0, 0, 1, 0 ],
                8  : [ 0, 0 ],
                9  : [ 0, 0 ],
                10 : [ 0, 0, 0, 1 ]
            }

    def default_moves():

        return []

    def print_move(self, moveno, move):
        print str(moveno) + ": " + str(move) + "\n"


    def __init__(self, _board=default_board(), _moves=default_moves(),
_types=default_types()):

        self.board = _board
        self.moves = _moves
        self.types = _types

    def possible_moves(self):

        moves_so_far = set()
        moves_so_far.add('x')
        moves_so_far.add(0)
        ret = []
        for y_idx in range(0, len(self.board)):
            for x_idx in range(0, len(self.board[y_idx])):

                piece = self.board[y_idx][x_idx]

                if not piece in moves_so_far:

                    moves = self.legal_moves(y_idx, x_idx)
                    moves_so_far.add(piece)

                    if moves:
                        ret.extend(moves)

        return ret

    def is_answer(self):

        if self.board[5][3] == 1:
            return True
        else:
            return False

    def legal_moves(self, ycoord, xcoord):

        ret = []
        for dir in [ [ 0, 1 ], [ 0, -1 ], [ 1, 0 ], [ -1, 0 ] ]:
            ret.extend(self.addmove(dir[0], dir[1], ycoord, xcoord))

        return ret

    def empty(self, type, ycoord, xcoord, pieceno):

        for itr in range(0, len(type), 2):

            yy = type[itr]
            xx = type[itr+1]

            if not (len(self.board) > (yy+ycoord) >= 0)  or not (len
(self.board[yy+ycoord]) > xx+xcoord >= 0):
                return False

            if not self.board[yy+ycoord][xx+xcoord] in [ 0, pieceno ]:
                return False

        return True

    def addmove(self, ymult, xmult, ycoord, xcoord):

        ret = []
        pieceno = self.board[ycoord][xcoord]
        type    = self.types[pieceno]

        if xmult != 0:
            for xx in range(xcoord + xmult, -1 if xmult < 0 else 4, -1
if xmult < 0 else 1):
#               if xx == 0:
#                   continue
                if self.empty(type, ycoord, xx, pieceno):
                    ret.append(self.newmove(ycoord, xcoord, ycoord,
xx ))
                else:
                    break

        if ymult != 0:
            for yy in range(ycoord + ymult, -1 if ymult < 0 else 6, -1
if ymult < 0 else 1):
#               if yy == 0:
#                   continue
                if self.empty(type, yy, xcoord, pieceno):
                    ret.append(self.newmove(ycoord, xcoord, yy,
xcoord))
                else:
                    break

        return ret

    def newmove(self, fromy, fromx, toy, tox):

        move = {
                'fromx' : fromx,
                'fromy' : fromy,
                'toy'   : toy,
                'tox'   : tox,
                'piece' : self.board[fromy][fromx]
                }

        return move

    def printout_path(self):

#       print self
        pdb.set_trace()
        answer = state()

        moveno = 0
        print "\n==========================\n"

        for moveno in range(0, len(self.moves)):
            move = self.moves[moveno]
            self.print_move(moveno, move)
            answer.apply_move(move)
            answer.print_board()
        print "\n==========================\n"

    def print_board(self):

        for xx in self.board:

            print ": ".join([ "%2s" % str(ii) for ii in xx ])

    def to_string(self):

        return str(self.board)

    def apply_move(self, move):

        self.moves.append(move)
        num = self.board[move['fromy']][move['fromx']]
        type = self.types[num]

        for idx in range(0,len(type),2):
            yy_delta = type[idx]
            xx_delta = type[idx+1]
            self.board[move['fromy']+ yy_delta][move['fromx']+
xx_delta] = 0

        for idx in range(0,len(type),2):
            yy_delta = type[idx]
            xx_delta = type[idx+1]
            self.board[move['toy']+ yy_delta][move['tox']+ xx_delta] =
num

    def next_states(self):

        ret = []
        for move in self.possible_moves():
            newstate = copy.deepcopy(self)
            newstate.apply_move(move)
            ret.append(newstate)

#        pdb.set_trace()
#        for xx in ret:
#            print xx.__dict__
#            print "\n"

        return ret

seen_states = set()

start = state()
dq    = deque()

dq.append(start)


while len(dq):

    curstate = dq.popleft()
    print "HERE " + str(curstate) + " => " + curstate.to_string() +
"\n"
    curstate.printout_path()

    if curstate.is_answer():
        curstate.printout_path()

    elif curstate.to_string() in seen_states:
        print "DUP " + curstate.to_string()

    else:
        seen_states.add(curstate.to_string())
        for state in curstate.next_states():
            if not state.to_string() in seen_states:
                dq.append(state)

                print "Trying..\n"
                state.print_board()
                print "\n"



More information about the Python-list mailing list