New inited instance of class?

S

Samuel Kleiner

Is there a builtin way of making making another instance of your own
class? I really expected type(self)(*args, **keywords) to work this way.
Currently i'm doing this:

def new(self,*args,**keywords):
from new import instance
s=instance(self.__class__)
if hasattr(D(),'__init__'):
s.__init__(*args,**keywords)
return s
 
D

Douglas Alan

Samuel Kleiner said:
Is there a builtin way of making making another instance of your own
class? I really expected type(self)(*args, **keywords) to work this way.

Doesn't self.__class__(*args, **keywords) work?

|>oug
 
F

Francis Avila

Samuel Kleiner wrote in message ...
Is there a builtin way of making making another instance of your own
class?

You mean, from the inside (from one of the instance methods of the class)?

def new(self, *args, **kargs):
return self.__class__(*args, **kargs)
I really expected type(self)(*args, **keywords) to work this way.

Works for me. What traceback does it give you?
Currently i'm doing this:

def new(self,*args,**keywords):
from new import instance
s=instance(self.__class__)
if hasattr(D(),'__init__'):
s.__init__(*args,**keywords)
return s

That's ugly.
 
S

Samuel Kleiner

Francis said:
Samuel Kleiner wrote in message ...

You mean, from the inside (from one of the instance methods of the class)?
Yes.

def new(self, *args, **kargs):
return self.__class__(*args, **kargs)

This works. Thanks.
Works for me. What traceback does it give you?

Not for me. I really want to call it as the function itself, and

type(self)(argument1,argument2,argument3)

fails with

Traceback (most recent call last):
File "<stdin>", line 139, in ?
File "<stdin>", line 78, in __add__
TypeError: instance() takes at most 2 arguments (3 given)

whereas

self.__class__(argument1,argument2,argument3)

does not
Currently i'm doing this:

[my code]
That's ugly.

Yes.
 
F

Francis Avila

Samuel Kleiner wrote in message ...
Not for me. I really want to call it as the function itself, and

type(self)(argument1,argument2,argument3)

fails with

Traceback (most recent call last):
File "<stdin>", line 139, in ?
File "<stdin>", line 78, in __add__
TypeError: instance() takes at most 2 arguments (3 given)

Ah! You're using classic classes. Don't do that.

Observe:

If you're curious, look in the Python Language Reference at the old and new
style classes to see the differences. There's absolutely no advantage to
old style classes, so stop usin' 'em.

There's a grand old intro (by Guido) to new-style classes at python.org,
linked from "What's New" in the 2.3 docs. I keep hunting for that link: it
really should be in the distributed docs, because it's vital for
understanding the still poorly-documented new-style classes.
 
S

Samuel Kleiner

Francis said:
Ah! You're using classic classes. Don't do that.

Ok, thanks-

So can I make all my classes derive from object without
doing so explicitly- IE, without having to change every
single top-level class definition?
 
F

Francis Avila

Samuel Kleiner wrote in message ...
Ok, thanks-

So can I make all my classes derive from object without
doing so explicitly- IE, without having to change every
single top-level class definition?

I doubt it. But I think sed or re could take care of that quite easily with
a search/replace.

Besides, "explicit is better than implicit." ;)
 
P

Peter Otten

Samuel said:
So can I make all my classes derive from object without
doing so explicitly- IE, without having to change every
single top-level class definition?

You can do it on a per-file basis by putting

__metaclass__ = type

once before the class definitions.

Peter
 
A

Aahz

If you're curious, look in the Python Language Reference at the old
and new style classes to see the differences. There's absolutely no
advantage to old style classes, so stop usin' 'em.

<raised eyebrow> In addition to the factors Fredrik mentioned, there's
also the issue that new-style classes are more of a moving target WRT
syntax and semantics; for complex uses, it can be tricky (or impossible)
to get the same code working the same way on both 2.2 and 2.3.

More than that, you *can't* use new-style classes for exceptions. So
please stop telling people to avoid classic classes.
 
F

Francis Avila

Peter Otten said:
You can do it on a per-file basis by putting

__metaclass__ = type

once before the class definitions.

That strikes me as a very *bad* idea, because it's no longer obvious that
the classes themselves are new-style, and the OP might develop a bad habit
of using this to avoid typing '(object)' all the time. (Or he might show us
all for fools, if ':' becomes shorthand for '(object):'.)

Aside from that, metaclasses are a more advanced and less-commonly-used
feature of classes, and therefore probably more vulnerable to change. I
know it should work, but am uneasy that it might manifest some unexpected
behavior (or bug).
 
F

Francis Avila

Fredrik Lundh wrote in message ...

That's not a big difference, and in any case:
http://www.python.org/doc/current/whatsnew/node17.html#SECTION00017200000000
00000000

Creation of new-style instances is faster. I seem to recall Alex Martelli
also thinking that new-style classes are faster all-around. In any case,
he's gung-ho on new-style classes, even more than I am.
classes.

documentation may also be seen as an advantage, of course.

True, but unless one is doing something elaborate (can't even think *what*)
or relies on the old mro, the only difference is that base classes will
derive from object. If there is code that depends upon the old mro, it
should probably be fixed anyway.

And it's probably not a problem. From "What's new in 2.3", section 16:
"""
The method resolution order used by new-style classes has changed, though
you'll only notice the difference if you have a really complicated
inheritance hierarchy. Classic classes are unaffected by this change. Python
2.2 originally used a topological sort of a class's ancestors, but 2.3 now
uses the C3 algorithm as described in the paper ``A Monotonic Superclass
Linearization for Dylan''. To understand the motivation for this change,
read Michele Simionato's article ``Python 2.3 Method Resolution Order'', or
read the thread on python-dev starting with the message at
http://mail.python.org/pipermail/python-dev/2002-October/029035.html.
Samuele Pedroni first pointed out the problem and also implemented the fix
by coding the C3 algorithm. """

So I still stand by the claim that one should stop using old-style classes.
Changing old-style to new-style classes is more problematic, but I don't see
that it's much more. If the code is old enough to use changed/depreciated
pre-2.2 features, changing classic classes to new-style is the least of your
problems. But if it's 2.2 code, the jump to 2.3 is small and nothing but an
advantage--only a policy decision should keep anyone in 2.2.

What are the serious compatibility problems with changing an old-style class
to a new-style class (which I haven't encountered)? My understanding is
that the headaches are from *mixing* classic and new-style classes in the
same hieararchy.
 
F

Francis Avila

Aahz wrote in message ...
<raised eyebrow> In addition to the factors Fredrik mentioned,

I responded to those concerns separately.
there's
also the issue that new-style classes are more of a moving target WRT
syntax and semantics; for complex uses, it can be tricky (or impossible)
to get the same code working the same way on both 2.2 and 2.3.

True, but if you are coding for both 2.2 and 2.3, you have to avoid a great
deal more than new-style classes (but, what changed besides the mro?). If
we're worried about compatability with pre-2.2, shouldn't we not be using
__class__ either? Barring trying to get code running on 2.2, it seems we
should be coding for new-style classes where possible, and it's possible
almost everywhere. Classic classes are on their way out, and eight more
keystrokes now means fewer headaches later.
More than that, you *can't* use new-style classes for exceptions.

Exceptions should be derived from Exception or a subclass thereof, so
whether they're new- or old-style is not an issue. When Python supports
new-style class exceptions, Exception will be changed to reflect that.
So
please stop telling people to avoid classic classes.

Someone better tell Alex Martelli, too, because IIRC he is far more gung-ho
on using new-style classes absolutely everywhere than I am. I believe he
said the only time he uses them is when he forgets to type (object), which
is about where I'm at.
 
P

Peter Otten

Francis said:
That strikes me as a very *bad* idea, because it's no longer obvious that
the classes themselves are new-style, and the OP might develop a bad habit
of using this to avoid typing '(object)' all the time. (Or he might show
us all for fools, if ':' becomes shorthand for '(object):'.)

I indeed expect the classic/new-style class schism to go away even before
3.0 and am looking forward to remove both (object) in class A(object): and
__metaclass__ = type, which I expect to be equally *not* hard :)
Aside from that, metaclasses are a more advanced and less-commonly-used
feature of classes, and therefore probably more vulnerable to change. I
know it should work, but am uneasy that it might manifest some unexpected
behavior (or bug).

For the above recipe to work you need not know what metaclasses are. I'm not
in the ignorance is good camp, though. The more people play with
metaclasses (are there any in production yet?), the sooner the strengths
and weaknesses of this construct will reveal.

If you have the appropriate tests and can make your program pass them by
providing an explicit object superclass instead of the __metaclass__ line,
the fix should be a breeze.


Peter
 
A

Aahz

Aahz wrote in message ...

Someone better tell Alex Martelli, too, because IIRC he is far more
gung-ho on using new-style classes absolutely everywhere than I am. I
believe he said the only time he uses them is when he forgets to type
(object), which is about where I'm at.

There's a big difference between being gung-ho on new-style classes and
telling people to stop using old-style classes. There's also a big
difference between saying, "I never use classic classes," and, "You
should avoid classic classes." I'll admit that Alex posts enough that I
don't read everything he says, but I don't recall him going as far as you
do -- and I'd be rather shocked if he did because he almost always
appropriately qualifies his advice.
 
M

Michael Hudson

for complex uses, it can be tricky (or impossible) to get the same
code working the same way on both 2.2 and 2.3.

Specific example? (I guess you're talking about C3 here?)

Cheers,
mwh
 
M

Michele Simionato

Francis Avila said:
"""
The method resolution order used by new-style classes has changed, though
you'll only notice the difference if you have a really complicated
inheritance hierarchy.

The "What's new" is right in practice, nevertheless, just for the sake
of
giving a counter-example, here is a very simple hierarchy which is
forbidden in 2.3 and valid in 2.2:
....
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
TypeError: Cannot create a consistent method resolution
order (MRO) for bases object, type

So I still stand by the claim that one should stop using old-style classes.

I don't disagree but see next point.
What are the serious compatibility problems with changing an old-style class
to a new-style class (which I haven't encountered)? My understanding is
that the headaches are from *mixing* classic and new-style classes in the
same hieararchy.

Not really, in my experience the mixture works well enough. Right now,
I see two other problems: 1) exceptions MUST be old style (as Aahz
already
pointed out) and 2) the are subtle differences in the working of
special methods such as __setattr__ and __getattr__ (and I think
Aahz was alluding to this too).
For new style classes x.__setattr__(k,v) is the same than
type(x).__setattr__(x,k,v) but the lookup rule is different for old
style classes. See the Nutshell for more.


Michele
 
M

Michele Simionato

Francis Avila said:
That strikes me as a very *bad* idea, because it's no longer obvious that
the classes themselves are new-style, and the OP might develop a bad habit
of using this to avoid typing '(object)' all the time. (Or he might show us
all for fools, if ':' becomes shorthand for '(object):'.)

I don't disagree.
Aside from that, metaclasses are a more advanced and less-commonly-used
feature of classes, and therefore probably more vulnerable to change. I
know it should work, but am uneasy that it might manifest some unexpected
behavior (or bug).

Maybe you are worrying a bit too much here, since the __metaclass__=type
idiom is quite safe in practice. Of course, it can give surprises,
such as the following:

__metaclass__=type

class E: pass

raise E() # not the error you would expect

Nevertheless, you should derive exceptions from Exception, so this
does not happen in real live. The other caution is with certain usages
of special methods, but they are relatively rare.

On the other hand, custom metaclasses different from type can
give more than one surprise, so I would not suggest their use to
the causal programmer. BTW, also the experienced programmer can
live without metaclasses for 99% of tasks. But they may come
handy in special situations.

Michele
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,172
Messages
2,570,934
Members
47,474
Latest member
AntoniaDea

Latest Threads

Top