使用外部 class 实例作为内部 class 中的自身?
Use outer class instance as self in inner class?
我正在为 GMAIL API 编写包装器。在这个包装器中,我试图在 "main class" 中包含子属性,以便它更紧密地遵循以下内容:
以前,我使用的方法如下:
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(...)
。上面有一些问题,它每次都重新定义 class ,我必须在每个方法上面添加 @staticmethod
作为它的一部分。我确实意识到我可以在外部 class 级别创建 class ,并为每个设置一个隐藏变量,然后 .method returns 或创建,但这似乎是太多的解决方法。
tldr: 是否可以将实例传递给内部 class 因为 self
是外部 class 的实例(我不希望必须将外部 class 的属性传递给每个内部 class)。
用户应该有一个消息实例,它允许方法获取。代码的 scetch 是:
class Messages:
...
def get()
...
class Users:
...
messages = Messages(...)
允许
users = Users()
users.messages.get()
这个 API 中的坏处是复数名称,这对 class 来说是个坏兆头。如果从头开始,您宁愿使用 classes User 和 Message,这更有意义。
如果您仔细查看您 link 提供的 API 中的 GET/POST 调用,您会注意到 url 类似于 UserId/settings
,这是另一个需要实施的提示用户 class,不是用户。
与其在 class 之间共享 self
参数,不如将需要的内容传递给实例化的 class 的构造函数可能更好。
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)
如果您需要向构造函数传递大量信息并且它开始变得笨拙,您可以将共享代码拆分为第三个 class,然后在测试和消息之间传递class作为单个对象。
在 Python 中,您可以使用 metaclasses 和魔术方法做各种聪明的事情,但在 99% 的情况下,只是将事情重构为不同的 class es 和函数将使您的代码更具可读性和可维护性。
self in the methods reference the self of the outer class
也许这就是你想要的factory-method
尽管我将在下面提供的示例代码可能与已经提供的答案类似,并且上面的 link 另一个答案可能会满足您的要求,因为它的形式略有不同我仍然会提供我对你所问内容的看法。代码不言自明。
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
方法方法对于标签、历史记录等都是相同的
编辑: 我会再试一次,试图了解你想要实现的目标,即使你说过
I have tried numerous things with defining the classes outside of the container class [...]
。我不知道您是否尝试过继承,因为您的内部 class me
,尽管它在这里并不代表什么,但看起来您仍然想以某种方式利用它的功能。你也说
self in the methods reference the self of the outer class
这对我来说听起来像是你想要在最后继承。
那么要走的路是(通过使用继承的邻近想法):
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
我认为这可能是比您内心的 class 方法更可取的方法,我认为,您会做出决定。请注意,在 python 中查找 getter 和 setter,如果您想坚持给出的继承想法,它可能会对您有所帮助。
我正在为 GMAIL API 编写包装器。在这个包装器中,我试图在 "main class" 中包含子属性,以便它更紧密地遵循以下内容:
以前,我使用的方法如下:
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(...)
。上面有一些问题,它每次都重新定义 class ,我必须在每个方法上面添加 @staticmethod
作为它的一部分。我确实意识到我可以在外部 class 级别创建 class ,并为每个设置一个隐藏变量,然后 .method returns 或创建,但这似乎是太多的解决方法。
tldr: 是否可以将实例传递给内部 class 因为 self
是外部 class 的实例(我不希望必须将外部 class 的属性传递给每个内部 class)。
用户应该有一个消息实例,它允许方法获取。代码的 scetch 是:
class Messages:
...
def get()
...
class Users:
...
messages = Messages(...)
允许
users = Users()
users.messages.get()
这个 API 中的坏处是复数名称,这对 class 来说是个坏兆头。如果从头开始,您宁愿使用 classes User 和 Message,这更有意义。
如果您仔细查看您 link 提供的 API 中的 GET/POST 调用,您会注意到 url 类似于 UserId/settings
,这是另一个需要实施的提示用户 class,不是用户。
与其在 class 之间共享 self
参数,不如将需要的内容传递给实例化的 class 的构造函数可能更好。
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)
如果您需要向构造函数传递大量信息并且它开始变得笨拙,您可以将共享代码拆分为第三个 class,然后在测试和消息之间传递class作为单个对象。
在 Python 中,您可以使用 metaclasses 和魔术方法做各种聪明的事情,但在 99% 的情况下,只是将事情重构为不同的 class es 和函数将使您的代码更具可读性和可维护性。
self in the methods reference the self of the outer class
也许这就是你想要的factory-method
尽管我将在下面提供的示例代码可能与已经提供的答案类似,并且上面的 link 另一个答案可能会满足您的要求,因为它的形式略有不同我仍然会提供我对你所问内容的看法。代码不言自明。
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
方法方法对于标签、历史记录等都是相同的
编辑: 我会再试一次,试图了解你想要实现的目标,即使你说过
I have tried numerous things with defining the classes outside of the container class [...]
。我不知道您是否尝试过继承,因为您的内部 class me
,尽管它在这里并不代表什么,但看起来您仍然想以某种方式利用它的功能。你也说
self in the methods reference the self of the outer class
这对我来说听起来像是你想要在最后继承。 那么要走的路是(通过使用继承的邻近想法):
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
我认为这可能是比您内心的 class 方法更可取的方法,我认为,您会做出决定。请注意,在 python 中查找 getter 和 setter,如果您想坚持给出的继承想法,它可能会对您有所帮助。