NOTE 1:
After writing this whole post, I realized that while you used @classmethod,
what you seem to really want is a fully @staticmethod class -- certainly
your example was a static method, and some other posters were talking about
static method (i.e. "it's bad style to have unused parameters in a
function") -- so this answer *may* be not quite write for your use case,
but it does apply to the example given. And I'm having a hard time figuring
out when one might want a fully classmethod class :-), so if that is what
you intended, please post an example that actually uses the "cls" parameter.

NOTE 2:
maybe it was email client mangling, but your code was using two spaces for
indentation (or were those tabs?), you really want to use four spaces to
indent in Python -- trust me on this!

Now the post:

It's really hard to see what you are really working with with such a
(necessarily) short example, but a couple notes:

Cars have different states, MovingCar, IdleCar, ParkingCar...
>
> A car can move between different states and it keeps the same information.
>

Why writing a module does not work has 2 parts, they may be due to my
> insufficient experience with python but I'm switching between the states as
> their API's are executed.


you could use modules as namespaces in this case -- modules are objects,
like everything else in Python, so you could do:

in AA.py:

def greet(A_instance):
     print("Hello", A_instance.name)

BB.py:

def greet(A_instance):
    print("Hello", A_instance.name)

main_module.py:

from . import AA, BB

class A:
    def __init__(self, state, name):
        self.state = state
        self.name = name

    def greet(self):
        self.state.greet(self)

    def switchAA(self):
        self.state = AA

    def switchBB(self):
        self.state = BB

and it should all work.

But I agree, that doesn't "feel" right.

However, a "state" to me sounds like a collection of static information --
could your state be stored as a collection of data, in a dict, or maybe a
dataclass? are there actually different methods (actions) involved, that
don't involve the state itself (i.e. self)?

To follow your example:


> class AA:
>   @classmethod
>   def greet(cls, A_instance):
>      print("Hello", A_instance.name)
>
> class BB:
>   @classmethod
>   def greet(cls, A_instance):
>     print("Hi", A_instance.name)
>

the difference between these is the content of the message, so you could
write:

from dataclasses import dataclass

@dataclass
class State():
    greeting: str

AA = State(greeting="Hello")
BB = State(greeting="Hi")

class A:
    def __init__(self, state, name):
        self.state = state
        self.name = name

    def greet(self):
        print(self.state.greeting, self.name)

    def switchAA(self):
        self.state = AA

    def switchBB(self):
        self.state = BB


if __name__ == "__main__":
    obj = A(AA, "alperen")
    obj.greet()
    obj.switchBB()
    obj.greet()

BTW: part of how I got to this solution is the DRY principle (Don't Repeat
Yourself): I looked at your AA and BB greet() methods, and it took me a
second to see what was different about them. They were repeated code: the
only difference was one string. You really don't need/want different
classes (or different methods) if the logic is the same.

But another way to do this, particularly if there IS some different logic
in your different State classes, would be to forget static methods, and
have the state stored in class attributes, and the logic in the methods:

class State:
     def greet(self, A_instance):
         print(self.greeting, A_instance.name)

class AA:
    greeting = "Hello"

class BB:
    greeting = "Hi"

It seems odd to have a subclass that only specifies a class attribute or
two, but if you really want to use classes in this way, it will accomplish
what you want.

All that being said, an "all_static" decorator, as suggested by Guido and
prototyped by Eric could be a reasonable way to create a collection of
methods in one namespace, if indeed, they are different methods.

-CHB

PS: A reminder about this list -- it's really a better idea for folks
fairly new to the language to start on another forum (e.g. tu...@python.org,
stack overflow, etc) and ask: "how to I accomplish this"? and see what you
get for answers, before you post an idea to ideas for a new language
feature.


-- 
Christopher Barker, PhD

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/Q6OZLNWFKAQEE5EU77CBKOKBODD53TOX/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to