Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #21121 > unrolled thread
| Started by | John Salerno <johnjsal@gmail.com> |
|---|---|
| First post | 2012-03-01 22:00 -0800 |
| Last post | 2012-03-01 23:16 -0800 |
| Articles | 8 — 3 participants |
Back to article view | Back to comp.lang.python
Is this the proper way to use a class method? John Salerno <johnjsal@gmail.com> - 2012-03-01 22:00 -0800
Re: Is this the proper way to use a class method? Chris Rebert <clp2@rebertia.com> - 2012-03-01 22:25 -0800
Re: Is this the proper way to use a class method? John Salerno <johnjsal@gmail.com> - 2012-03-01 23:16 -0800
Re: Is this the proper way to use a class method? Ian Kelly <ian.g.kelly@gmail.com> - 2012-03-02 01:04 -0700
Re: Is this the proper way to use a class method? Chris Rebert <clp2@rebertia.com> - 2012-03-02 00:08 -0800
Re: Is this the proper way to use a class method? John Salerno <johnjsal@gmail.com> - 2012-03-02 10:51 -0800
Re: Is this the proper way to use a class method? John Salerno <johnjsal@gmail.com> - 2012-03-02 10:51 -0800
Re: Is this the proper way to use a class method? John Salerno <johnjsal@gmail.com> - 2012-03-01 23:16 -0800
| From | John Salerno <johnjsal@gmail.com> |
|---|---|
| Date | 2012-03-01 22:00 -0800 |
| Subject | Is this the proper way to use a class method? |
| Message-ID | <4136337.363.1330668021961.JavaMail.geo-discussion-forums@ynjd19> |
This is purely for fun and learning, so I know there are probably better ways of creating a chess program. Right now I'm just curious about my specific question, but I'd love to hear any other advice as well.
Basically, I'm wondering if I'm using the class method properly with the move method. The reason I did it this way is because every chess piece will obviously have its own move method, yet they will all need to mark the piece as moved, so I figure that's best written once in the superclass.
This works, but doing it this way seems weird, since the point of a class method is that it can be called by the class itself, even before instances have been created. Yet the way I've implemented it, it is necessarily tied to being called on an instance. Is this wrong? Is there a better way to do what I'm doing with move?
Also, do I need the @classmethod decorator? The book I'm reading says to use it (and @staticmethod), but the following code works without it.
Thanks.
class ChessPiece:
def __init__(self, position, label, has_moved):
try:
self.position = (position[0], int(position[1]))
except TypeError:
self.position = position
self.label = label
self.has_moved = has_moved
def move(cls, self):
self.has_moved = True
class Pawn(ChessPiece):
def __init__(self, position=None, label=1, has_moved=False):
super().__init__(position, label, has_moved)
def move(self):
super().move(self)
self.position = (chr(ord(self.position[0]) + 1), self.position[1] + 1)
[toc] | [next] | [standalone]
| From | Chris Rebert <clp2@rebertia.com> |
|---|---|
| Date | 2012-03-01 22:25 -0800 |
| Message-ID | <mailman.339.1330669514.3037.python-list@python.org> |
| In reply to | #21121 |
On Thu, Mar 1, 2012 at 10:00 PM, John Salerno <johnjsal@gmail.com> wrote: > This is purely for fun and learning, so I know there are probably better ways of creating a chess program. Right now I'm just curious about my specific question, but I'd love to hear any other advice as well. > > Basically, I'm wondering if I'm using the class method properly with the move method. Unfortunately, no. > The reason I did it this way is because every chess piece will obviously have its own move method, yet they will all need to mark the piece as moved, so I figure that's best written once in the superclass. Right, but why not just a regular instance method? The method in question doesn't operate upon *the class itself* at all (which is the raison d'etre of classmethods); it instead operates upon an instance. A staticmethod would be slightly less weird, but really, it should just be an instance method. > This works, but doing it this way seems weird, since the point of a class method is that it can be called by the class itself, even before instances have been created. Yet the way I've implemented it, it is necessarily tied to being called on an instance. Is this wrong? Is there a better way to do what I'm doing with move? Just make it a normal instance method (i.e. remove the `cls` argument). > Also, do I need the @classmethod decorator? The book I'm reading says to use it (and @staticmethod), but the following code works without it. That's just a coincidence. Your supercall is ought to be: super().move() In contrast, super().move(self) calls the superclass instance method `move` with 2 arguments, both `self`, which just happens to work given your move() method, inside which `cls` isn't actually a class like it ought to be. <snip> > class ChessPiece: > > def __init__(self, position, label, has_moved): > try: > self.position = (position[0], int(position[1])) > except TypeError: > self.position = position > self.label = label > self.has_moved = has_moved > > def move(cls, self): > self.has_moved = True > > > class Pawn(ChessPiece): > > def __init__(self, position=None, label=1, has_moved=False): > super().__init__(position, label, has_moved) > > def move(self): > super().move(self) > self.position = (chr(ord(self.position[0]) + 1), self.position[1] + 1) Cheers, Chris
[toc] | [prev] | [next] | [standalone]
| From | John Salerno <johnjsal@gmail.com> |
|---|---|
| Date | 2012-03-01 23:16 -0800 |
| Message-ID | <21646224.4.1330672614560.JavaMail.geo-discussion-forums@ynt13> |
| In reply to | #21122 |
> That's just a coincidence. Your supercall is ought to be: super().move() > In contrast, super().move(self) calls the superclass instance method > `move` with 2 arguments, both `self`, which just happens to work given > your move() method, inside which `cls` isn't actually a class like it > ought to be. Thank you! This is the whole reason I tried using a class method in the first place. I was getting an error that said my move method only takes one argument, but I was passing in two. But if I make the super call as super().move(), how does that work? The move method in the superclass takes an argument, and if I just do super().move(), isn't it the subclass that's getting passed to it? How does the superclass move method know what 'self' is if it doesn't get passed to it as I did originally?
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2012-03-02 01:04 -0700 |
| Message-ID | <mailman.344.1330675495.3037.python-list@python.org> |
| In reply to | #21125 |
On Fri, Mar 2, 2012 at 12:16 AM, John Salerno <johnjsal@gmail.com> wrote: >> That's just a coincidence. Your supercall is ought to be: super().move() >> In contrast, super().move(self) calls the superclass instance method >> `move` with 2 arguments, both `self`, which just happens to work given >> your move() method, inside which `cls` isn't actually a class like it >> ought to be. > > Thank you! This is the whole reason I tried using a class method in the first place. I was getting an error that said my move method only takes one argument, but I was passing in two. > > But if I make the super call as super().move(), how does that work? The move method in the superclass takes an argument, and if I just do super().move(), isn't it the subclass that's getting passed to it? The self that gets passed into the superclass.move() or the subclass.move() is the exact same object in either case. There is no "up-casting" (or any casting at all, for that matter) in Python. > How does the superclass move method know what 'self' is if it doesn't get passed to it as I did originally? super() called without arguments is equivalent to super(<class this method was defined in>, self) -- it collects the value of self from the current stack frame. So self is able to be passed in because the super object implicitly knows what self is. Cheers, Ian
[toc] | [prev] | [next] | [standalone]
| From | Chris Rebert <clp2@rebertia.com> |
|---|---|
| Date | 2012-03-02 00:08 -0800 |
| Message-ID | <mailman.345.1330675701.3037.python-list@python.org> |
| In reply to | #21125 |
On Thu, Mar 1, 2012 at 11:16 PM, John Salerno <johnjsal@gmail.com> wrote:
>> That's just a coincidence. Your supercall is ought to be: super().move()
>> In contrast, super().move(self) calls the superclass instance method
>> `move` with 2 arguments, both `self`, which just happens to work given
>> your move() method, inside which `cls` isn't actually a class like it
>> ought to be.
>
> Thank you! This is the whole reason I tried using a class method in the first place. I was getting an error that said my move method only takes one argument, but I was passing in two.
>
> But if I make the super call as super().move(), how does that work? The move method in the superclass takes an argument, and if I just do super().move(), isn't it the subclass that's getting passed to it?
The instance of the subclass (i.e. what Pawn.move() considers `self`)
gets passed to it.
> How does the superclass move method know what 'self' is if it doesn't get passed to it as I did originally?
Oh, but it does get passed, just implicitly. `super()` basically grabs
`self` magically from its caller, and uses it to bind method calls on
the magical object returned by `super()`.
`super().move()` ends up being, in this particular case, equivalent to:
ChessPiece.move(self)
which is incidentally how one would write this without using super().
Here is a useful[1] "identity" to ponder:
x.y(z) === type(x).y(x, z)
Cheers,
Chris
--
[1]: In the sense of a useful lie[2]; it's far from completely
accurate; it (at the least) ignores metaclasses, overridings of
__getattribute__(), and a third thing that's difficult to clearly put
into words.
[2]: http://c2.com/cgi/wiki?UsefulLie [3]
[3]: Yes, my footnotes have footnotes.
http://rebertia.com
[toc] | [prev] | [next] | [standalone]
| From | John Salerno <johnjsal@gmail.com> |
|---|---|
| Date | 2012-03-02 10:51 -0800 |
| Message-ID | <18263375.25.1330714301799.JavaMail.geo-discussion-forums@vbdj6> |
| In reply to | #21131 |
> Oh, but it does get passed, just implicitly. `super()` basically grabs > `self` magically from its caller, and uses it to bind method calls on > the magical object returned by `super()`. Thanks again, now I understand :)
[toc] | [prev] | [next] | [standalone]
| From | John Salerno <johnjsal@gmail.com> |
|---|---|
| Date | 2012-03-02 10:51 -0800 |
| Message-ID | <mailman.347.1330714310.3037.python-list@python.org> |
| In reply to | #21131 |
> Oh, but it does get passed, just implicitly. `super()` basically grabs > `self` magically from its caller, and uses it to bind method calls on > the magical object returned by `super()`. Thanks again, now I understand :)
[toc] | [prev] | [next] | [standalone]
| From | John Salerno <johnjsal@gmail.com> |
|---|---|
| Date | 2012-03-01 23:16 -0800 |
| Message-ID | <mailman.342.1330672617.3037.python-list@python.org> |
| In reply to | #21122 |
> That's just a coincidence. Your supercall is ought to be: super().move() > In contrast, super().move(self) calls the superclass instance method > `move` with 2 arguments, both `self`, which just happens to work given > your move() method, inside which `cls` isn't actually a class like it > ought to be. Thank you! This is the whole reason I tried using a class method in the first place. I was getting an error that said my move method only takes one argument, but I was passing in two. But if I make the super call as super().move(), how does that work? The move method in the superclass takes an argument, and if I just do super().move(), isn't it the subclass that's getting passed to it? How does the superclass move method know what 'self' is if it doesn't get passed to it as I did originally?
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web