@anatoly60

Как переписать код с PHP на Python?

Как переписать следующий код с PHP на Python, сохранив автозагрузку классов?

Файл Bar1.php:
<?php

class Bar1 {
    public function baz() {
        echo __CLASS__, PHP_EOL;
    }
}

Файл Foo.php:
<?php

/**
 * Class Foo
 * @property Bar1 bar1
 * @property Bar2 bar2
 * ...
 * @property Bar10 bar10
 */
class Foo {
    public function &__get($property)
    {
        if (preg_match('/^bar([0-9]+)$/', $property)) {
            $className = ucfirst($property);
            if (!class_exists($className)) {
                throw new Exception('Invalid property');
            }
            $params = array('some', 'params');
            $this->$property = new $className($params);
        } else {
            throw new Exception('Invalid property');
        }
        return $this->$property;
    }
}

Файл test.php:
<?php

function __autoload($class_name) {
    include $class_name . '.php';
}

$foo = new Foo();
$foo->bar1->baz();

//Bar1


UPD: Вот, что получилось:
Файл bar1.py:
class Bar1:
    def __init__(self, params):
        self.params = params

    def baz(self):
        print self.params

Файл foo.py:
import re
from get_class import get_class


class Foo:
    def __getattr__(self, attr):
        if re.match('^bar([0-9]+)$', attr):
            class_name = attr[0].upper() + attr[1:]
            obj = get_class(attr + '.' + class_name)
            params = ['some', 'params']
            self.attr = obj(params)
        else:
            raise Exception('Invalid attr')

        return self.attr

Файл get_class.py:
def get_class(cls):
    parts = cls.split('.')
    module = ".".join(parts[:-1])
    m = __import__(module)
    for comp in parts[1:]:
        m = getattr(m, comp)
    return m

Файл get_class.py:
from foo import Foo

foo = Foo()
foo.bar1.baz()


Вот бы еще кто подсказал аналог phpDoc комментария "@property Bar1 bar1" для автокомплита в PyCharm.
  • Вопрос задан
  • 3786 просмотров
Пригласить эксперта
Ответы на вопрос 2
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
1) так как в python есть система модулей, автозагрузка не нужна. Просто импортируете нужные модули. Каждый файл - модуль. Если в директории есть файл __init__.py, то вся директория - пакет модулей, по сути тот же модуль который содержит другие модули...

2) https://docs.python.org/3.4/tutorial/classes.html - классы в python

3) stackoverflow.com/questions/8258819/comparing-phps... - разьяснение по поводу магического __get в php и аналогия для python. Точнее объяснение различий в объектной модели (к слову почитайте в документации).

4) https://docs.python.org/3.3/library/re.html - регулярки

ну и т.д. Так же все интанцируемые классы должны быть импортированы перед использованием.
Ответ написан
@bromzh
Drugs-driven development
Вот бы еще кто подсказал аналог phpDoc комментария "@property Bar1 bar1" для автокомплита в PyCharm.

Docutils, Pycharm умеет её анализировать. Разметка там в нормальном RestructuredText. Плюс, есть отличная система документации Sphinx.
Вот пример оформления docstring для функции:
def public_fn_with_sphinxy_docstring(name, state=None):
    """This function does something.

    :param name: The name to use
    :type name: str
    :param state: Current state to be in
    :type state: bool
    :returns:  the return code
    :rtype: int
    :raises: AttributeError, KeyError

    """
    return 0

Или, более компактно:
def public_fn_with_sphinxy_docstring(name, state=None):
    """This function does something.

    :param str name: The name to use
    :param bool state: Current state to be in
    :returns:  int - the return code
    :raises: AttributeError, KeyError
    """
    return 0


Кроме того, в 3-й ветке питона есть поддержка аннотаций типов (можно указывать тип аргументов функции и возвращаемый тип). Pycharm это тоже понимает.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы