我有使用自定义getter的类,所以当我需要使用自定义getter以及需要使用默认值的情况时,我会遇到这种情况。
请考虑遵循。
如果我以这种方式调用对象c的方法:
c.somePyClassProp
在这种情况下我需要调用自定义getter,getter将返回int值,而不是Python对象。 但是如果我以这种方式调用方法:
c.somePyClassProp.getAttributes()
在这种情况下我需要使用默认的setter,并且首先返回需要是Python对象,然后我们需要调用返回的python对象的getAttributes方法(来自c.somePyClassProp)。 注意somePyClassProp实际上是class的属性,它是另一个Python类实例。
那么,在Python中有什么办法可以知道在第一次方法调用之后是否会调用其他方法吗?
答案 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()