Использовать экземпляр внешнего класса как себя во внутреннем классе? - PullRequest
0 голосов
/ 16 сентября 2018

Я пишу оболочку для GMAIL API .В этой оболочке я пытаюсь включить податрибуты в «основной класс», чтобы он более точно соответствовал следующему:

picture

Ранее я использовалметоды, такие как:

class Foo:
    def __init__(self, ...):
        # add some attributes

    def get_method(self, ...):
        return some_stuff

Это позволяет мне сделать foo.get_method(...).Чтобы следовать GMAIL API, я пытаюсь сделать:

class Foo:
     def __init__(self, ...):
         # add some attributes

     @property
     def method(self):
         class _Method:
             @staticmethod
             def get(self, ...):
                 return some_stuff
         return _Method()

, что позволяет мне делать foo.method.get(...).Выше есть некоторые проблемы, он каждый раз переопределяет класс, и я должен добавить @staticmethod над каждым методом как его часть.Я понимаю, что мог бы создать класс на уровне внешнего класса и установить скрытую переменную для каждой, которую затем возвращает или создает .method, но это кажется слишком большим обходным решением.

tldr : возможно ли сделать экземпляр переданным во внутренний класс, так как self будет экземпляром внешнего класса (я не хочу передавать атрибутывнешний класс для каждого внутреннего класса).

Ответы [ 3 ]

0 голосов
/ 16 сентября 2018

Вместо того, чтобы делить параметр self между классами, вам, вероятно, лучше просто передать все, что вам нужно, в конструктор создаваемого вами класса.

class Messages:
    def __init__(self, name):
        self.name = name

    def method(self, other_arg):
        return self.name + other_arg

class Test:
    name = "hi"

    def __init__(self):
        self.messages = Messages(name=self.name)

Если вам нужно передать много информации конструктору, и она начинает становиться громоздкой, вы можете сделать что-то вроде разделения общего кода на третий класс, а затем передать его между классами Test и Messages как один объект.

В Python есть все виды умных вещей, которые вы можете делать с метаклассами и магическими методами, но в 99% случаев простой рефакторинг вещей в разные классы и функции даст вам более читаемый и поддерживаемый код.

0 голосов
/ 16 сентября 2018

self в методах ссылается на self внешнего класса

возможно это то, что вы хотите фабричный метод

Хотя приведенный ниже пример кода может быть похож на уже предоставленные ответы, и ссылка на другой ответ, приведенная выше, может удовлетворить ваше желание, поскольку он немного отличается, но я все же предоставлю свое видение того, что вы спросили , Код не требует пояснений.

class User:
    def __init__(self, pk, name):
        self.pk = pk
        self.name = name
        self._messages = None

    def messages(self):
        if self.messages is None:
            self._messages = Messages(self.pk)
        return self._messages


class Messages:
    def __init__(self, usr):
        self.usr = usr

    def get(self):
        return self._grab_data()

    def _grab_data(self):
        # grab the data from DB
        if self.usr == 1:
            print('All messages of usr 1')
        elif self.usr == 2:
            print('All messages of usr 2')
        elif self.usr == 3:
            print('All messages of usr 3')



one = User(1, 'One')
two = User(2, 'Two')
three = User(3, 'Three')

one.messages().get()
two.messages().get()
three.messages().get()

Практический подход messages будет таким же, как для меток, истории и т. Д.

Редактировать: Я еще раз попробую сам, пытаясь понять, чего вы хотите достичь, даже если вы сказали, что

Я пробовал множество вещей с определением классов вне класса контейнера [...]

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

self в методах ссылается на self внешнего класса

Для меня это звучит так, будто ты хочешь наследства в конце. Тогда путь будет (идея близости с использованием наследования):

class me(object):
    def __init__(self):
        self.__other_arg = None # private and hidden variable
    # setter and getter methods
    def set_other_arg(self, new_other_arg):
        self.__other_arg = new_other_arg
    def get_other_arg(self): 
        return self.__other_arg

class Test(me):
    name = 'Class Test'
    @property
    def message(self):
        other_arg = self.get_other_arg()
        if other_arg is not None:
            return '{} {}'.format(self.name, other_arg)
        else:
            return self.name

t = Test()
t.set_other_arg('said Hello')
print(t.message)
# output >>> Class Test said Hello

Я думаю, что это может быть предпочтительнее, чем ваш внутренний класс, мое мнение, вы решите. Только одна заметка, ищите getter и setter в python, это может помочь вам, если вы хотите придерживаться идеи наследования.

0 голосов
/ 16 сентября 2018

У пользователей должен быть экземпляр сообщений, что позволяет получать метод.Эскиз кода:

class Messages:
      ...
      def get()
            ...


class Users:
      ...
      messages = Messages(...)

позволяет

users =  Users()
users.messages.get()

Плохая вещь в этом API - это множественные имена, что является плохим признаком для класса.Если бы все было сделано с нуля, вы бы предпочли иметь классы User и Message, которые имеют больше смысла.

Если вы ближе познакомитесь с вызовами GET / POST в предоставленном вами API-интерфейсе, вы заметите, что URL-адреса выглядят как UserId/settings, еще один совет для реализации класса User, а не Users.

...