Как динамически выбирать подкласс из унаследованного класса при определении глобальных методов

Это мой первый настоящий набег на классы Python, поэтому прошу прощения за неправильное употребление терминов.

Я пытаюсь использовать подход Factory Pattern для динамического выбора подкласса на основе URL-адреса предоставляется пользователем. Вот установка, которая у меня есть:

import requests
from bs4 import BeautifulSoup as BS

class Templates(object):
    def __init__(self, url):
        self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0'}
        self.url = url

    def url(self):
        return self.url

    def response(self):
        return self.response

    def text(self):
        return self.text

    def dom(self):
        return self.dom

    @staticmethod
    def get_template(url):
        headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0'}
        response = requests.get(url, headers=headers)
        text = response.text
        if 'Website by Dealer.com' in text:
            return Dealer(url)
        else:
            return None

class Dealer(Templates):
    def __init__(self, url):
        Templates.__init__(self, url)
        self.new_vehicle_url = "{}/new-inventory/index.htm".format(self.url.rstrip('/'))
        self.used_vehicle_url = "{}/used-inventory/index.htm".format(self.url.rstrip('/'))

Что я хочу сделать, так это вызвать Templates.get_template(url) и вернуть соответствующий подкласс. Этот вопрос сделал его очень простым, но мне что-то не хватает в процессе, потому что я также хочу определить общие методы в моем классе Templates, что требует от меня передачи url в Template.

Каким способом Pythonic это настроить, чтобы следующий код работал?

template = Templates().get_template(url) # assume returns Dealer()
template.url
# 'http://www.some-website.com'
template.response.status_code
# 200

person tblznbits    schedule 01.08.2017    source источник
comment
Почему Templates.get_template(url) не работает?   -  person juanpa.arrivillaga    schedule 01.08.2017
comment
В любом случае, обычно вы использовали бы classmethod вместо staticmethod. Откровенно говоря, я вижу использование staticmethod только людьми, пришедшими с таких языков, как Java, которые не допускают функций на уровне модулей и не могут избавиться от этой привычки.   -  person juanpa.arrivillaga    schedule 01.08.2017


Ответы (1)


В вашем коде вы используете Templates(), но на самом деле он пытается создать экземпляр Templates, что не удается, потому что отсутствует параметр url для Templates.__init__.

Но вам не нужен экземпляр для вызова статического метода:

template = Templates.get_template(url) # assume returns Dealer()
template.url
# 'http://www.some-website.com'
template.response.status_code
# 200

Я только что удалил там () после Templates.

person MSeifert    schedule 01.08.2017
comment
Всегда бывает что-то простое ... спасибо за помощь! - person tblznbits; 01.08.2017
comment
@brittenb Нет проблем. Рад помочь :) - person MSeifert; 01.08.2017