如何创建一个带多个点的类方法?

1 投票
2 回答
3504 浏览
提问于 2025-04-17 19:11

在Python中,我想创建一个(类)方法,里面有多个点,这样我就可以测试一些xmlrpc的方法,因为这些方法的名字可能会有很多点。当我尝试下面这个代码时:

class Foo(object):
    def method.with.many.dots(self):
        return 42

我遇到了语法错误。我还尝试了一些更复杂的想法,比如:

class Foo(object):
    def __getattr__(self, attr):
        print attr

但这些方法对于带点的函数名也不管用。有没有什么简单的方法可以让我创建一个模拟对象,这样我就可以在Python代码中做类似于:

mock.some.test.with.many.dots()

而不需要启动一个xmlrpc服务器?

2 个回答

2

这个解决方案是可行的。

输入:

import mock
MO = mock.Mock()
MO.some.test.wyth.many.dots.return_value = 42
MO.some.test.wyth.many.dots()

输出:

42

注意,“with”是一个关键字。

每个带点的“后代”都是一个独立的(模拟的)对象。

8
class Foo(object):
    def __init__(self):
        self._attr_path = []

    def __getattr__(self, attr):
        self._attr_path.append(attr)
        return self

    def __call__(self, *args, **kw):
        print ".".join(self._attr_path)
        print args, kw
        del self._attr_path[:]

f = Foo()
f.a.b.c(1,2,3)

这个输出:

a.b.c
(1, 2, 3) {}

要解决 @Daira Hopwood 的问题:

class Bar(object):
    def __init__(self, foo, attr):
        self.foo = foo
        self._attr_path = [attr]

    def __getattr__(self, attr):
        self._attr_path.append(attr)
        return self

    def __call__(self, *args, **kw):
        print self
        print args, kw

    def __str__(self):
        return ".".join(self._attr_path)

class Foo(object):

    def __getattr__(self, attr):
        return Bar(self, attr)

f = Foo()
f.a.b.c(1,2,3)

再次解决 @Daira Hopwood 的问题:

class Foo(object):

    def __init__(self, parent=None, name=""):
        self.parent = parent
        self.name = name

    def __getattr__(self, attr):
        return Foo(parent=self, name=attr)

    def __call__(self, *args, **kw):
        print self
        print args, kw    

    def __str__(self):
        nodes = []
        node = self
        while node.parent:
            nodes.append(node)
            node = node.parent
        return ".".join(node.name for node in nodes[::-1])

f = Foo()
x = f.a.b
y = f.a.c
x()
y()

g = f.a
f.b
g.b.c() 

撰写回答