0

I have a class in crawl.py that's like this:

from myapp.crawl import ScrapyCommand

class Command(ScrapyCommand):

    name = 'someotherapp.crawl' #this should be the dynamic import

    def handle(self, *args, **options):
        super(Command, self).handle(self, *args, **options)
        ...
        ...< custom code >
        ...

and a file called list.py contains:

from myapp.list import ScrapyCommand

class Command(ScrapyCommand):

    name = 'someotherapp.list' #this should be the dynamic import

    def handle(self, *args, **options):
        super(Command, self).handle(self, *args, **options)
        ...
        ...< some other custom code >
        ...

This class that they both inherit called ScrapyCommand from two separate files - myapp/crawl.py and myapp/list.py. The ScrapyCommand that is inherited by crawl.py looks like this:

from someotherapp.crawl import OtherCommand

class ScrapyCommand(OtherCommand):     

    def __init__(self, *args, **kwargs):
        ...
        ...

    def handle(self, *args, **options):
        return

The ScrapyCommand that is inherited by list.py looks like this:

from someotherapp.list import OtherCommand

class ScrapyCommand(OtherCommand):

    def __init__(self, *args, **kwargs):
        ...
        ...

    def handle(self, *args, **options):
        return

I've edited this code for brevity. The logic in the ScrapyCommand is simple and both these files contain exactly the same code except the import statement. Look at the imports.

I'm looking to reduce the amount of duplication of code. Is there a way, I could make the base class dynamically import it's own base class. The code in crawl.py and list.py is different but the code in their base-class is exactly the same. When list.py imports it's base-class i.e. ScrapyCommand, that class should import it's base-class i.e. OtherCommand from a file that I specify dynamically in the name parameter.

How can I do this? I haven't been able to figure out an easier way of doing this and I'm only going down this rabbit hole because I have quite a few Commands and I could greatly reduce the amount of duplicated code. Thanks for reading this.

--

As for thew name attribute. I'm not entirely bent on using a class attribute. If you can suggest a better store the import statement I'd go with that but I would need to obviously have that import somewhere. Where should I put it? Thanks

2 Answers 2

2

If you absolutely must do this by using a class attribute, you can use a metaclass. However, I don't see a reason, at least from what you described, that you couldn't just statically import one or both base classes as needed. You also might be served better by using multiple inheritance rather than trying to shoehorn things in to a single inheritance hierarchy.

Sign up to request clarification or add additional context in comments.

1 Comment

I'm not entirely bent on using a class attribute. If you can suggest a better way I'd go with that but I would need to obviously have that import somewhere. Where should I put it? Thanks.
1

You could construct a class from a function. Does this solve your problem?

def make_scrapy_command_class(base_class):
    class ScrapyCommand(base_class):
        # your methods here
        pass

    return ScrapyCommand

ScrapyCommand = make_command_class(someotherapp.crawl.OtherCommand)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.