Как программно преобразовать одноэлементный объект на основе «пользовательского класса» в модуль Python? - PullRequest
0 голосов
/ 16 мая 2018

Я бы хотел программно преобразовать одноэлементный объект в модуль Python, чтобы я мог напрямую использовать методы этого одноэлементного объекта, импортируя их через модуль, а не обращаясь к ним как к атрибутам объекта. Под «программно» я подразумеваю, что я не хочу явно копировать и вставлять методы класса в файл модуля. Мне нужен какой-то обходной путь, который позволяет мне импортировать методы объекта в глобальную область видимости другого модуля.

Я был бы очень признателен, если бы кто-то мог помочь мне в этом.

Вот базовый пример, который должен проиллюстрировать мою проблему:

mymodule.py

class MyClass:
"""This is my custom class"""
    def my_method(self):
        return "myValue"

singleton = MyClass()

main_as_is.py

from mymodule import MyClass

myobject = MyClass()
print(myobject.my_method())

main_to_be.py

from mymodule import my_method # or from mymodule.singleton import my_method

print(my_method())

1 Ответ

0 голосов
/ 18 мая 2018

Вы можете использовать ту же стратегию, что и стандартный модуль random.Все функции в этом модуле на самом деле являются методами "частного" экземпляра класса Random.Это удобно для большинства распространенных применений модуля, хотя иногда полезно создавать свои собственные экземпляры Random, чтобы вы могли иметь несколько независимых случайных потоков.

Я адаптировал ваш код для иллюстрации этой техники.Я назвал класс и его экземпляр с единственным начальным подчеркиванием, так как это обычное соглашение в Python для обозначения частного имени , но имейте в виду, что это просто соглашение, Python не предпринимает никаких действий для обеспечения этогоКонфиденциальность.

mymodule.py

class _MyClass:
    """ This is my custom class """
    def my_method(self):
        return "myValue"

_myclass = _MyClass()
my_method = _myclass.my_method

main_to_be.py

from mymodule import my_method

print(my_method())       

выход

myValue

Кстати, from mymodule import method1, method2 Синтаксис в порядке, если вы импортируете только небольшое количество имен или из имени ясно, из какого модуля он (например, функции и константы математического модуля), и вы не импортируете из многих модулей.В противном случае лучше использовать синтаксис такого типа

import mymodule as mm
# Call a method from the module
mm.method1()

Таким образом, очевидно, какие имена являются локальными, а какие импортированы и откуда они импортированы.Конечно, он немного больше печатает, но делает код на целом намного более читабельным.И это исключает возможность конфликтов имен.

FWIW, вот способ автоматизировать добавление всех методов _myclass без явного перечисления их (но помните, что «явный лучше, чем неявный»).В конце «mymodule.py» вместо my_method = _myclass.my_method добавьте следующее:

globals().update({k: getattr(_myclass, k) for k in _MyClass.__dict__ 
    if not k.startswith('__')})

Я не могу рекомендовать это, поскольку он напрямую вводит элементы в globals() dict.Обратите внимание, что этот код добавит все атрибуты класса, а не только методы.


В своем вопросе вы говорите об одноэлементных объектах.Мы обычно не используем синглтоны в Python, и многие программисты на разных языках ООП считают их анти-паттернами.Подробнее см. https://stackoverflow.com/questions/12755539/why-is-singleton-considered-an-anti-pattern.Для этого приложения совершенно не нужно использовать синглтон.Если вам нужен только один экземпляр _MyClass, просто не создавайте другой экземпляр, просто используйте экземпляр, который mymodule создает для вас.Но если ваш начальник настаивает на том, что вы должны использовать синглтон, см. Пример кода здесь .

...