1

This is what it does: The content of the first instance of the class ( in this case mok1 ) gets filled with water. I can fill it infinitely but as soon as the first instance is created, I can only fill that instance and generate a error by any other instance. Is there a cleaner and better way to do this? Now I use the difference in the class's var and the instance's var which is confusing for people because it are different variables. Thnx guys;)

class mok:
    _content = 'EMPTY'
    def __init__( self flavour ):
        self.flavour = flavour

    def fill( self ):
        if mok._content == 'EMPTY':
            self._content = '1'
            mok._content = 1

        if self._content == '1':    
            print 'Filling mok!'
        else:
            print 'Error: This is a different mok!'

mok1 = mok( 'thea' )    
mok2 = mok( 'coffee' )

mok1.fill()
mok1.fill()
mok2.fill()
mok1.fill()

output:

Filling mok!

Filling mok!

Error: This is a different mok!

Filling mok!

I've found the solution:

class mok:
    _mok_with_water = 0

    def __init__( self, color, flavour ):
        self.color = color
        self.flavour = flavour

    def printcolor( self ):
        print 'Mok color =', self.color
    print 'Mok flavour =', self.flavour

    def fill( self ):
    self.printcolor()
        if mok._mok_with_water == 0:
        mok._mok_with_water = self

    if mok._mok_with_water == self:
        print 'Filling mok!'
    else:
        print 'Error: This is a different mok!'

    def empty( self ):
        if self == mok._mok_with_water:
            mok._mok_with_water = 0

mok1 = mok( 'geel', 'thee' )    
mok2 = mok( 'zwart', 'koffie' )

mok1.fill()
mok1.fill()
mok2.fill()
obj = mok1.empty()
obj = mok2.fill()
obj = mok1.fill()
Jim Clermonts
  • 1,694
  • 8
  • 39
  • 94

4 Answers4

0

I think the question is related to that of how to effectively implement a Singleton. While you apparently want to allow multiple instances (hence you don't have a Singleton), you still need to identify that first instance.

The problem with your solution is that you are not identifying the first instance, but the first instance on which you called Fill().

You need to set your class variable in the constructor. Maybe this excellent Wikipedia article provides some additional ideas.

cdonner
  • 37,019
  • 22
  • 105
  • 153
  • No i'm not supposed to use a singleton. If I set the variable in the constructor, a user can manipulate the working of the program. I have to change something within the class. – Jim Clermonts Aug 31 '11 at 08:25
0

Why are you doing it? Try:

class mok():

    def __init__(self, flavour):

        self.flavour = flavour
        self.is_empty = True

    def fill(self):

        print 'Filling mok!'
        self.is_empty = False


mok1 = mok('coffe')
mok2 = mok('tea')

mok1.fill()
mok1.fill()
mok2.fill()
mok1.fill()

Output:

Filling mok!
Filling mok!
Filling mok!
Filling mok!

I'm confused...

CNS709
  • 136
  • 4
  • 1
    How is `class mok():` better than `class mok:`? – pillmuncher Aug 30 '11 at 21:20
  • I prefer an uniform syntax. I prefer use always the same syntax `class ([]): ` – CNS709 Sep 04 '11 at 20:57
  • Obviously you're using Python 2.x, where `class mon():` and `class mok:` both create an old style class, whereas `class mok(object):` would create a new style class. Chances are, you don't really want an old style class, or do you? – pillmuncher Sep 04 '11 at 21:18
0

So you want a class that only allows you to fill instances of the first type created?

class ContentError(Exception):
    pass

class Mok(object):

    _content = None

    def __init__(self, flavour):
        self.flavour = flavour
        if Mok._content is None:
            Mok._content = flavour

    def fill(self):
        if self._content == self.flavour:
            print 'Filling!'
        else:
            raise ContentError('This is a different mok!')
Klohkwherk
  • 279
  • 3
  • 7
  • Right you are, it's fixed now! – Klohkwherk Aug 31 '11 at 20:34
  • No this also doesn't work, because when I flip mok2 and mok1, `code` mok2 = mok( 'coffee' ) mok1 = mok( 'thea' ) mok1.fill() `code` It now recognizes mok2 as the first instance! – Jim Clermonts Sep 01 '11 at 14:59
  • I don't understand - in the example you've just given mok2 is the first instance. Or do you maybe mean that you can only fill the first instance created, so mok1 = mok('Tea'), mok2 = Mok('Tea') should produce an error if you try and do mok2.fill() ? – Klohkwherk Sep 02 '11 at 03:15
0

From a Java perspective this could be solved by a Factory pattern.

You'd have 2 classes Mok, which can't be filled, and FillableMok which inherits Mok (and thus is-a Mok) which can be filled. The factory only ever produces a single FillableMok (essentially a singleton), all the others are default, non-fillable Moks.

class Mok(Object):
    def fill(self):
        raise CannotBeFilledException()

class FillabelMok(Mok):
    def fill(self):
        filled = True # or whatever

class Factory(Object):
    _fillableMok = None

    def createMok(self):
        if _fillableMok:
           return Mok()
        _fillableMok = FillableMok()
        return _fillableMok()

This may not be syntactically correct as it has been a while since I used Python. But the idea is hopefully clear. Improvements welcome.

extraneon
  • 23,575
  • 2
  • 47
  • 51