Thanks for the feedback, Gregor Vern Ceder schrieb: > Gregor, > > I don't feel authoritative on the correctness/appropriateness of the > implementation, but I do agree completely that behavior b, or what you > have in the 3.0 version, is vastly preferable. > > Cheers, > Vern > > Gregor Lingl wrote: >> Hi, >> >> this posting - concerning the new turtle module - goes to the >> Python-Dev and Python-3000 lists and to a couple of 'power users' of >> turtle graphics, hoping to recieve feedback from the developer's >> point of view as well as from the user's point of view. >> >> Currently the implementations of the turtle.Screen class for Python >> 2.6 and Python 3.0 differ by a 'tiny' detail with an important >> difference in behaviour. So clearly this has to be resolved before >> the final release.(The origin of this difference is, that when I >> ported turtle.py to Python 3.0 I discovered (and 'fixed') what I now >> consider to be a bug in the 2.6 version.) I'd like to ask you kindly >> for your advice to achieve an optimal solution. >> >> The posting consists of three parts: >> 1. Exposition of design goals >> 2. Problem with the implementation 3. How to solve it? >> >> Preliminary remark: I've had some discussions on this topic before >> but I still do not see a clear solution. Moreover I'm well aware of >> the fact that using the Singleton pattern is controversial. So ... >> >> 1. Exposition of design goals >> ... why use the Singleton design pattern? The turtle module contains >> a TurtleScreen class, which implements methods to control the drawing >> area the turtle is (turtles are) drawing on. It's constructor needs a >> Tkinter Canvas as argument. In order to avoid the need for users to >> tinker around with Tkinter stuff there is the Screen(TurtleScreen) >> class, designed to be used by beginners(students, kids,...), >> particularly in interactive sessions. >> >> A (THE (!)) Screen object is essentially a window containing a >> scrolled canvas, the TurtleScreen. So it's a ressource which should >> exist only once. It can be constructed in several ways: >> - implicitely by calling an arbitrary function derived from a >> Turtle-method, such as forward(100) or by constructing a Turtle such >> as bob = Turtle() >> - implicitely by calling an arbitrary function derived from a Screen >> method, such as bgcolor("red") >> - explicitely by calling it's constructor such as s = Screen() >> Anyway this construction should only happen if a Screen object >> doesn't exist yet. >> Now for the pending question: What should happen, when s = Screen() >> is called explicitely and there exists already 'the' Screen object. >> (i) Clearly s should get a reference to the existing Screen object, >> but ... >> (ii) (a)... should s be reinitialized (this is the case now in Python >> 2.6), or >> (b)... should s be left untouched (this is the case now in Python >> 3.0) >> >> I, for my part, prefer the latter solution (b). Example: a student, >> having (interactively) produced some design using some turtle t = >> Turtle() decides spontaneously to change backgroundcolor. s = >> Screen(); s.bgcolor("pink") should do this for her - instead of >> deleting her design and moreover her turtle. To reinitialize the >> screen she still can use s.clear(). >> >> Of course, there are workarounds to achieve the same effect also with >> solution (a), for instance by assigning s = Screen() *before* drawing >> anything or by assigning s = t.getscreen(). But imho (which derives >> itself from my experience as a teacher) solution (b) supports better >> the oop-view as well as experimenting spontaneously in interactive >> sessions. >> >> 2. Problem with the implementation >> The task is to derive a Singleton class from a Nonsingleton class >> (Screen from TurtleScreen). The current implementations of the Screen >> 'Singleton' both use the Borg idiom. Just for *explaining* the >> difference between the two versions of class Screen here concisely, >> I'll use a 'standard' Singleton pattern (roughly equivalent to the >> Borg idiom): >> >> class Spam(object): >> def __init__(self, s): >> self.s = s >> >> class SingleSpam(Spam): >> _inst = None >> def __new__(cls, *args, **kwargs): if cls != >> type(cls._inst): >> cls._inst = Spam.__new__(cls, *args, **kwargs) >> return cls._inst >> def __init__(self, s): >> if vars(self): return ###### should this be here??? >> Spam.__init__(self, s) >> >> Shortly, this means that SingleSpam.__init__() acts like an empty >> method whenever a (the!) SingleSpam object already exists. 3.0 >> version of Screen acts like this. By contrast 2.6 version of Screen >> acts as if the butlast line were not there and thus reinitializes the >> Screen object. >> >> 3. How to solve it? >> >> Main question: which *behaviour* of the Screen class should be >> preferred. If 3.0, is it feasible and correct not to call the >> constructor of the parent class if the object already exists? >> >> Additional question: Do you consider the Borg idiom a good solution >> for this task or should the standard singleton pattern as shown above >> be preferred. Or would you suggest a solution/an approach different >> from both? >> >> Thanks for your patience, and - in advance - for your assistance >> >> Regard, >> Gregor >> >> >> >> >
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4