1

我有自定义 getter 的类,所以我有需要使用自定义 getter 的情况,以及需要使用默认值的情况。

所以考虑跟随。

如果我以这种方式调用对象 c 的方法:

c.somePyClassProp

在这种情况下,我需要调用自定义 getter,getter 将返回 int 值,而不是 Python 对象。但是如果我以这种方式调用方法:

c.somePyClassProp.getAttributes()

在这种情况下我需要使用默认的setter,首先返回需要是Python对象,然后我们需要调用返回的python对象的getAttributes方法(来自c.somePyClassProp)。请注意, somePyClassProp 实际上是另一个 Python 类实例的类的属性。

那么,在 Python 中有没有什么方法可以让我们知道在第一次方法调用之后是否会调用其他方法呢?

4

4 回答 4

4

No.c.someMethod是一个独立的表达方式;它的评估不会受到使用结果的环境的影响。如果有可能实现您想要的,这将是结果:

x = c.someMethod
c.someMethod.getAttributes() # Works!
x.getAttributes()            # AttributeError!

这会令人困惑。

不要试图c.someMethod根据将要做什么来做出不同的行为,如果可能的话,根本不要进行c.someMethod方法调用。人们期望c.someMethod返回一个绑定的方法对象,然后可以调用该对象来执行该方法;只需def以通常的方式调用该方法并使用c.someMethod().

于 2013-07-26T22:13:12.647 回答
3

您不想根据接下来访问的属性返回不同的值,而是希望返回一个int类似对象的对象,该对象具有所需的属性。为此,我们创建了一个int具有getAttributes()方法的子类。当然,这个类的实例需要知道它“绑定”到什么对象,即它的getAttributes()方法应该引用什么对象,所以我们将 this 添加到构造函数中。

class bound_int(int):
    def __new__(cls, value, obj):
        val = int.__new__(cls, value)
        val.obj = obj
        return val
    def getAttributes(self):
        return self.obj.somePyClassProp

现在在你的 getter 中c.somePyClassProp,不是返回一个整数,而是返回 abound_int并将它传递给它的getAttributes()方法需要知道的对象的引用(这里我只是让它引用它self,它是从返回的对象):

@property
def somePyClassProp(self):
   return bound_int(42, self)

这样,如果您使用c.somePyPclassPropas an int,它的行为就像任何其他int,因为它是一个,但如果您想进一步调用getAttributes()它,您也可以这样做。两种情况下的值相同;它只是为了满足这两个目的而建造的。这种方法可以适应几乎任何此类问题。

于 2013-07-26T22:35:02.930 回答
0

看起来您想要两种方法来获取该属性,具体取决于您想要使用它做什么。我认为没有任何固有的 Pythonic 方式来实现这一点,因此您需要为每种情况存储一个变量或属性名称。也许:

c.somePyClassProp

可以在函数中使用,__get__并且 c.somePyClassProp__getAttributes() 可以在__getattribute__函数内部以更自定义的方式实现。

我使用的一种方法(这可能不是最好的)是检查该确切的变量名称:

def __getattribute__(self, var_name):
    if ('__' in var_name):
        var_name, method = var_name.split('__')
    return object.__getattribute__(self, var_name).__getattribute__(method)

Usingobject.__get__(self, var_name)使用对象类的直接获取属性的方法。

于 2013-07-26T22:30:44.057 回答
0

您可以将包含的 Python 对象存储为变量,并通过 @property 析取器为您想要的任何值创建 getter。当您想读取 int 时,请引用该属性。当您想要包含的对象时,请改用其变量名。

class SomePyClass(object):
    def getInt(self):
        return 1
    def getAttributes(self):
        return 'a b c'

class MyClass(object):

    def __init__(self, py_class):
        self._py_class = py_class

    @property
    def some_property(self):
        return self._py_class.getInt()

x = MyClass(SomePyClass())
y = self.some_property
x._py_class.getAttributes()
于 2013-07-26T23:35:35.300 回答