Python 如果传递了类实例,如何执行函数?

Python 如果传递了类实例,如何执行函数?,python,python-3.x,callable,callable-object,Python,Python 3.x,Callable,Callable Object,我目前有一个可调用的TestClass。可调用函数执行一个函数,如果任何属性等于None,该函数将引发异常。将其定义为可调用的目的是,当TestClass实例被传递到另一个函数或被复制时,它将在传递之前检查所有属性是否存在,否则将引发异常 下面显示此逻辑的行是UsesTestClass(testClass()) 理想情况下,我希望能够执行相同的检查,而不必“调用”类实例。例如,UsesTestClass(testClass)。是否有神奇的方法或其他方式来配置类,使其能够在作为参数传递之前执行函数

我目前有一个可调用的
TestClass
。可调用函数执行一个函数,如果任何属性等于
None
,该函数将引发异常。将其定义为可调用的目的是,当
TestClass
实例被传递到另一个函数或被复制时,它将在传递之前检查所有属性是否存在,否则将引发异常

下面显示此逻辑的行是
UsesTestClass(testClass())

理想情况下,我希望能够执行相同的检查,而不必“调用”类实例。例如,
UsesTestClass(testClass)
。是否有神奇的方法或其他方式来配置类,使其能够在作为参数传递之前执行函数

class TestClass:
    def __init__(self):
        self.name = None

    def run(self):
        if self.name is None:
            raise Exception("'name' attribute is 'None'")

    def __call__(self):
        self.run()
        return self

def UsesTestClass(testClass):
    print(testClass.name)

testClass = TestClass()
testClass.name = "Hello"
UsesTestClass(testClass())

如果使用集成到python中的类型库,就可以做到这一点

import types


class TestClass:
    def __init__(self):
        self.name = None

    def __getattribute__(self, attr):
        method = object.__getattribute__(self, attr)
        if not method:
            raise Exception("Attribute %s not implemented" % attr)
        if type(method) == types.MethodType:
            self.run()
        return method

    def run(self):
        if self.name is None:
            raise Exception("'name' attribute is 'None'")

    def __call__(self):
        self.run()
        return self


def UsesTestClass(testClass):
    print(testClass.name)


testClass = TestClass()
testClass.name = "Hello"
UsesTestClass(testClass)

您是否考虑过确保始终设置
name
的其他方法?例如,您可以要求将其传递给构造函数,然后将其设置为只读属性或在其setter中检查
None
。一般来说,最好使数据结构不处于无效状态,而不是不断检查无效状态。我考虑过将变量传递给构造函数。在我的用例中,TestClass中的属性是通过多个步骤而不是一次填充的。在
TestClass
中添加一个方法,该方法检查所需属性的状态,如果有异常,则引发异常。
UsesTestClass()
可以使用该类以及类本身中的方法。在我看来,通过
\uuuuu call\uuuuu()
这样做似乎有点奇怪,可能会产生误导。首先,“传递到另一个函数或复制”部分听起来像是从更像C++的角度思考,其中对象复制非常常见,在这里,复制/移动/等操作为您正在考虑的挂钩类型提供了更多的机会。Python不是这样工作的。第二,即使你正在寻找的钩子已经存在,在对象已经处于有效状态很久之后,它也会被重复调用,这会浪费很多时间。谢谢!它工作得很好。虽然当
self.name=None
时,它似乎在
raiseexception(“方法%s未实现”%attr)
处引发异常,但即使忽略在错误的时间进行验证的事实,它也确实存在错误。例如,你得到无限递归。