繁体   English   中英

Python 从 class 返回不同 class 的实例而不是自己

[英]Python return instance of a different class from class instead of self

我将尽力解释我要完成的工作。 我正在尝试从 class 而不是 return self返回一个新的 class 的实例。 请参考示例代码中的注释。

class Test(object):
    def __init__(self, a):
        self.a = a

    def methoda(self):
        return len(self.a)


class SomeClass(object):
    def __init__(self, lol):
        self.lol = lol
        self.test = Test(self.lol)

    def __call__(self):
        return self.test # this isnt going to work


c = SomeClass('bar')
print(c) # trying to access the Test class attributes and methods  here
# so in the above example, i want to do
# print(c.a) # print bar
# print(c.length() # print 3

__repr____str__在这种情况下不起作用,因为我试图让Test class object 回来。 我在SomeClass中尝试过的其他事情有self.test = Test(self.lol)类的东西,但这似乎并不完全符合我的要求。

我怎样才能做到这一点?

您可以覆盖SomeClass__getattr__方法,以便可以将SomeClass object 中未定义的属性委托给self.test

class Test(object):
    def __init__(self, a):
        self.a = a

    def methoda(self):
        return len(self.a)

class SomeClass(object):
    def __init__(self, lol):
        self.lol = lol
        self.test = Test(self.lol)

    def __getattr__(self, item):
        return getattr(self.test, item)

c = SomeClass('bar')
print(c.methoda())

这输出:

3

不太相信用例,但您可以在SomeClass中使用一些代理方法(在需要时使用property )将调用委托给相应的Test方法:

In [343]: class Test(object): 
     ...:     def __init__(self, a): 
     ...:         self.a = a 
     ...:  
     ...:     def methoda(self): 
     ...:         return len(self.a) 
     ...:  
     ...:  
     ...: class SomeClass(object): 
     ...:     def __init__(self, lol): 
     ...:         self.lol = lol 
     ...:         self.test = Test(self.lol) 
     ...:      
     ...:     @property 
     ...:     def a(self): 
     ...:         return self.test.a 
     ...:          
     ...:     def length(self): 
     ...:         return self.test.methoda() 
     ...:  
     ...:     def __call__(self): 
     ...:         return self.test 
     ...:                                                                                                                                                                                                   

In [344]: c = SomeClass('bar')                                                                                                                                                                              

In [345]: c.a                                                                                                                                                                                               
Out[345]: 'bar'

In [346]: c.length()                                                                                                                                                                                        
Out[346]: 3

另请注意,您可以调用SomeClass实例,即c ,因为您定义了__call_-方法,并返回Test实例。 这样,您可以使用以下方法获取值:

In [347]: print(c())                                                                                                                                                                                        
<__main__.Test object at 0x7fba862fc3c8>

In [348]: print(c().a)                                                                                                                                                                                      
bar

In [349]: print(c().methoda())                                                                                                                                                                              
3
  • 为此,您需要了解何时调用__init__以及何时__call__
class foo(object):
    def __init__(self, lol):
        print('__init__ called')
    def __call__(self):
        print('__call__ called')

ob = foo('lol')
print(ob())
_ = foo('lol')()
  • 这将是 output:
__init__ called # ob = foo('lol')
__call__ called # print(ob())
__init__ called # _ = foo('lol')()
__call__ called # _ = foo('lol')()
  • __init__在 class 被实例化时被调用。 当您将 class 的 object 称为 function 时,将调用__call__

  • 要在您的情况下访问Test class,您可以执行以下操作。

c = SomeClass('bar')
test_c = c()
print(c.a)
print(c.methoda)

您正在寻找的是__new__特殊方法。 它允许从头开始构建从 class 创建的 object:

class SomeClass(object):
    def __new__(cls, lol):
        obj = Test(lol)
        return obj

然后你可以使用它:

>>> c = SomeClass('bar')
>>> c
<__main__.Test object at 0x03F87750>
>>> c.a
'bar'
>>> c.methoda()
3

但是除非您将Test SomeClass的子类,否则您不应该这样做。 SomeClass('bar')返回一个不是SomeClass的 object 至少是不常见的,你可能会因此而被烧毁......

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM