如何知道python中请求的下一个属性

时间:2013-07-26 22:09:05

标签: python

我有使用自定义getter的类,所以当我需要使用自定义getter以及需要使用默认值的情况时,我会遇到这种情况。

请考虑遵循。

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

c.somePyClassProp

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

c.somePyClassProp.getAttributes()

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

那么,在Python中有什么办法可以知道在第一次方法调用之后是否会调用其他方法吗?

4 个答案:

答案 0 :(得分:4)

没有。 c.someMethod是一个独立的表达;其评估不受结果使用环境的影响。如果有可能实现你想要的,那就是结果:

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

这会让人感到困惑。

请勿尝试使c.someMethod的行为有所不同,具体取决于将对其执行的操作,如果可能,请勿对c.someMethod进行方法调用。人们期望c.someMethod返回一个绑定的方法对象,然后可以调用该对象来执行该方法;只需def方法通常的方法,并使用c.someMethod()调用它。

答案 1 :(得分:3)

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

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

现在在c.somePyClassProp的getter中,不是返回一个整数,而是返回bound_int并向其传递对getAttributes()方法需要了解的对象的引用(此处为I& #39;我只是引用self,它是从中返回的对象:

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

这样,如果您将c.somePyPclassProp用作int,则其行为与其他任何int一样,因为它是一个,但如果您想进一步调用getAttributes()在它上面,你也可以这样做。在这两种情况下,它的价值相同;它只是为了实现这两个目的而建造的。这种方法可以适应这种类型的任何问题。

答案 2 :(得分: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)

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

答案 3 :(得分:0)

您可以将包含的python对象存储为变量,并通过@property dectorator将get getters存储为您想要的任何值。如果要读取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()