Reputation: 1781
I'm working on the simple strategy
pattern implementation. I came to Python from Java world so I divided all classes to separate files as this seems ok for me. But I have troubles with packages and imports, please see the below code for details.
So I have a duck and 2 incapsulated behaviors: fly and quack.
Overall structure is:
behavior/
├── __init__.py
├── __init__.pyc
├── __pycache__
│ └── __init__.cpython-37.pyc
├── fly
│ ├── FlyBehavior.py
│ ├── FlyBehavior.pyc
│ ├── FlyNoWay.py
│ ├── FlyRocketPowered.py
│ ├── FlyRocketPowered.pyc
│ ├── FlyWithWings.py
│ ├── __init__.py
│ ├── __init__.pyc
│ └── __pycache__
│ ├── FlyBehavior.cpython-37.pyc
│ ├── FlyRocketPowered.cpython-37.pyc
│ └── __init__.cpython-37.pyc
└── quack
├── MuteQuack.py
├── Quack.py
├── QuackBehavior.py
├── Squeak.py
└── __init__.py
duck
├── Duck.py
├── MallardDuck.py
├── ModelDuck.py
├── __init__.py
├── __init__.pyc
└── __pycache__
├── Duck.cpython-37.pyc
├── MallardDuck.cpython-37.pyc
└── __init__.cpython-37.pyc
MiniDuckSimulator.py
MiniDuckSimulator.pyc
Fly classes:
FlyBehavior.py
from abc import ABC, abstractmethod
class FlyBehavior(ABC):
@abstractmethod
def fly(self):
pass
FlyNoWay.py
from behavior.fly import FlyBehavior
class FlyNoWay(FlyBehavior):
def fly(self):
print("I can't fly")
FlyRocketPowered.py
from behavior.fly import FlyBehavior
class FlyRocketPowered(FlyBehavior):
def fly(self):
print("I'm flying with a rocket")
FlyWithWings.py
from behavior.fly import FlyBehavior
class FlyWithWings(FlyBehavior):
def fly(self):
print("I'm flying!")
Quack classes:
QuackBehavior.py
from abc import ABC, abstractmethod
class QuackBehavior(ABC):
@abstractmethod
def quack(self):
pass
Quack.py
from behavior.quack import QuackBehavior
class Quack(QuackBehavior):
def quack(self):
print('Quack')
MuteQuack.py
from behavior.quack import QuackBehavior
class MuteQuack(QuackBehavior):
def quack(self):
print('<< Silence >>')
Squeak.py
from behavior.quack import QuackBehavior
class Squeak(QuackBehavior):
def quack(self):
print('Squeak')
Duck classes:
Duck.py
from abc import ABC, abstractmethod
class Duck(ABC):
fly_behavior = None
quack_behavior = None
@abstractmethod
def display(self):
pass
def perform_fly(self):
self.fly_behavior.fly()
def perform_quack(self):
self.quack_behavior.quack()
def swim(self):
print('All ducks float, even decoys!')
MallardDuck.py
from duck import Duck
class MallardDuck(Duck):
def __init__(self):
self.quack_behavior = Quack()
self.fly_behavior = FlyWithWings()
def display(self):
print("I'm a real Mallard duck")
ModelDuck.py
from duck import Duck
class ModelDuck(Duck):
def __init__(self):
self.fly_behavior = FlyNoWay()
self.quack_behavior = Quack()
def display(self):
print("I'm a model duck")
And main class:
MiniDuckSimulator.py
from duck import MallardDuck
from duck import ModelDuck
import behavior.fly.FlyRocketPowered as FlyRocketPowered
if __name__ == "__main__":
mallard = MallardDuck()
mallard.display()
mallard.perform_fly()
mallard.perform_quack()
model = ModelDuck()
model.display()
model.perform_fly()
model.fly_behavior = FlyRocketPowered()
model.perform_fly()
Program output:
$ python MiniDuckSimulator.py
Traceback (most recent call last):
File "MiniDuckSimulator.py", line 1, in <module>
from duck import MallardDuck
File "/Users/p/Documents/Develop/patterns_book/00_strategy/py/duck/MallardDuck.py", line 3, in <module>
class MallardDuck(Duck):
TypeError: module() takes at most 2 arguments (3 given)
What's wrong with my modules? Is my approach for storing and structuring code/classes ok? Thanks.
Upvotes: 0
Views: 74
Reputation: 29099
It should be
from duck.MallardDuck import MallardDuck
The MallardDuck
you are importing is still a file, not a class, even though it has a single class in it.
Change all of your other imports in a similar manner.
some notes:
Upvotes: 4