当前位置: 代码迷 >> python >> 在内部类中使用外部类实例作为自己?
  详细解决方案

在内部类中使用外部类实例作为自己?

热度:27   发布时间:2023-06-19 09:28:41.0

我正在为编写包装器。 在这个包装器中,我试图在“主类”中包含子属性,因此它更接近以下内容:

以前,我使用的方法是:

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传递给内部类的实例作为外部类的实例(我不希望必须将外部类的属性传递给每个内部类)。

用户应该有一个消息实例,它允许方法 get。 代码的 scetch 是:

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


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

允许

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

这个 API 的坏处是复数名称,这对类来说是个坏兆头。 如果从头开始,您宁愿拥有 User 和 Message 类,这更有意义。

如果您仔细查看链接提供的 API 中的 GET/POST 调用,您会注意到 url 类似于UserId/settings ,这是实现 User 类而不是 Users 的另一个提示。

与其在类之间共享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% 的情况下,只需将事物重构为不同的类和函数,就会使您的代码更具可读性和可维护性。

方法中的 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

我认为这可能是一种更好的方式,而不是您的内部课程方法,我认为,您将决定。 只是一方面,在python中查找getter和setter,如果您想坚持给定的继承思想,它可能会对您有所帮助。

  相关解决方案