On Mon, Jun 1, 2009 at 2:27 AM, Alan Gauld <alan.ga...@btinternet.com>wrote:
> > "Kent Johnson" <ken...@tds.net> wrote > >> > Yesterday, I posted a question to python-list involving custom >> > deepcopies in an inheritance hierarchy. I haven't received any >> >> ISTM that in general B.__deepcopy__() should call A.__deepcopy__() to do >> the "A" part of the work. In your example, this won't work because >> A.__deepcopy__() assumes that subclasses have a one-argument constructor. >> So, I would say that B is not fulfilling the contract assumed by A. >> > > I've been trying to think of a clear way to reply to this but kept getting > sucked into discussions of the Liskoff Substitution Principle and Law of > Demeter and such. Kent's explanation is much clearer! > > But this example highlights a real problem (IMHO) with dynamic OOP > languages like Python. You can write classes that examine themselves at > runtime and manipulate attributes that were actually > provided by subclasses (or even by the application writer!). This makes any > attempt at things like deepcopy fraught with difficulty because the clear > separation of concerns between parent and subclass has been broken. > > It is very important for good OO design that classes only operate on their > own data. But when you can dynamically add attributes to instances after > theit creation, as you can in Python, it's almost impossible to distinguish > between attributes of the parent class and the subclass. It's one of the > penalties of Python's dynamic nature and there is no easy solution to the > general case. In the specific case you need to read the code of both parent > and subclass and the application(s) using them! > > What if you give B a one-arg constructor by making the bTag argument >> optional? Then I think B.__deepcopy__() can call A.__deepcopy__(), then do >> the "B" part of the copy on the result. >> > > As a minimum subclasses should adhere to the parent interface. > Unfortunately because Python only allows a single constructor that can be a > limiting factor :-( > ( Multiple constructors (or factory methods) is one feature I would like > to see added to Python! ) > Wouldn't it be possible to create sort of a... bastardization? i.e. def __init__(self, *args): if len(args) == 0: #do something if len(args) == 1: #do something else etc.? Or would that create more problems than is worth it? -Wayne
_______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor