2013-07-26 57 views
1

我有自定义getter的类,所以我需要使用自定义getter的情况以及需要使用default的情况。如何知道在Python中请求哪个下一个属性

所以考虑以下。

如果我调用对象C的方法是这样的:

c.somePyClassProp 

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

c.somePyClassProp.getAttributes() 

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

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

+1

唯一可能的方式做你想做的就是让'c.somePyClassProp'返回你想要的两个接口的对象,联合收割机(部分或全部)。也就是说,你需要它看起来像一个'int',但也有'getAttributes'方法。如果你需要它可以做任何不平凡的事情,它将是混乱和复杂的。你确定你不能使用不同的方法或属性名来区分两种用途吗? – Blckknght

+0

Kindall的答案似乎是最好的,但前提是你可以在所有上下文中表现为int的对象,除了**它还支持getAttributes方法。 –

回答

3

你不想根据下一个访问哪个属性返回不同的值,你想返回一个int类似的对象,具有所需的属性。为此,我们创建一个int的子类,该子类具有getAttributes()方法。当然,这个类的一个实例需要知道它“绑定”了什么对象,也就是它的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 

现在您的getter方法c.somePyClassProp,而不是返回一个整数,你返回bound_int,并把它传递给其getAttributes()方法需要了解的对象的引用(在这里我就必须把它转交self ,对象它正在从返回):

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

这样一来,如果你使用c.somePyPclassPropint,它的行为就像任何其他int,因为它是一个,但如果你想进一步呼吁getAttributes()就可以了,你也能做到。在两种情况下都是相同的价值;它只是为了实现这两个目的而建立的。这种方法可以适应几乎任何类型的问题。

+0

虽然这在技术上起作用,但它非常令人困惑。一个int值为3的'bound_int'将打印为'3'并且看起来几乎完全像一个真正的'3',但它会失败'type'检查并导致内存泄漏,如果'bound_int'大于它的创建对象。你不想调试由看起来像'3'的东西引起的内存泄漏。 – user2357112

+0

只要你以正确的方式执行它,就可以通过类型检查,即使用'issubclass()'。您的其他关注点虽然在技术上不是内存泄漏,但它是一个很好的观点,并且需要注意的是,如果所涉及的对象很大。有很多情况下'bound_int'完全消失,避免了这个问题,但是在很多情况下,它不会。 – kindall

+0

您可以使用'weakref.ref'来存储对其他对象的引用,以避免强制它在需要时在内存中挂起。 – kindall

4

No. c.someMethod是一个独立的表达式;其评估不会受到使用结果的背景的影响。如果有可能达到你想要的,这将是结果:

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

这会混淆为地狱。

不要试图使c.someMethod的行为有所不同,具体取决于使用它的方式,并且如果可能的话,根本不要使c.someMethod成为方法调用。人们会期望c.someMethod返回一个绑定的方法对象,然后可以调用它来执行该方法;只需按照常规方法def即可,并将其与c.someMethod()联系起来。

+0

Tnx在你的答案。其实在我的情况下'someMethod'不是方法,它是其他Python类,所以,我会编辑我的问题 – user232343

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)采用直接获取属性的对象类的方法。

+0

对不起,这是一个混乱,应该使用'__getattribute__'方法。 – smakateer

0

您可以将包含的python对象作为变量存储,并通过@property dectorator为所需的任何值存储create 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() 
相关问题