简体   繁体   English

如何在 Python 中覆盖属性获取器

[英]How to override a property getter in Python

I have a class with a property called sessionID.我有一个带有名为 sessionID 的属性的类。 From that class I've derived a new class and would like to implement some other functionality in the property getter and property setter.我从那个类派生了一个新类,并希望在属性获取器和属性设置器中实现一些其他功能。 I seem to have the property setter working correctly, but for some strange reason the getter always executes the getter on the base class.我似乎让属性设置器正常工作,但由于某种奇怪的原因,getter 总是在基类上执行 getter。 Any of you guys have an idea what I'm doing wrong, or what I could change "你们中的任何一个人都知道我做错了什么,或者我可以改变什么”

Base Class :基类:

class workflowerAPIBase(object):
    _sessionID = None
    _IP        = None

    @property
    def sessionID(self):
        return self._sessionID

    @sessionID.setter
    def sessionID(self, value):
        self._sessionID = value

Descendant Class :后代阶层:

class workflowerAPI(workflowerAPIBase):
    session = None

    @property
    def sessionID(self):
        # Try to get the previous sessionID from the Session ... 
        # we will still have to check if that sessionID is valid though
        if ( 'sessionID' in self.session ):
            self._sessionID = self.session['sessionID']

        # If no sessionID was found, try to use a default one for now
        # by generating a loginPrintersCloud using default login info
        if ( self._sessionID == None ) or ( self._sessionID == '' ):
            result = self.defaultlogin
            self._sessionID = result['sessionID']

        return self._sessionID

    @workflowerAPIBase.sessionID.setter
    def sessionID(self, value):
        # Store the new sessionID in our session for later use
        if ( self.session != None ):
            self.session['sessionID'] = value

        # call the inherited sessionID setter
        workflowerAPIBase.sessionID.fset( self, value )
        #super(workflowerAPI, self).sessionID(self, value)
#        self._sessionID = value

    def __init__(self, request):
        if request != None and request.session != None and request.session.has_key('sessionID'):
            self.session   = request.session
            self.sessionID = request.session['sessionID']

        super(workflowerAPI, self).__init__()

I'm not sure what I'm doing wrong, but each time the value of the sessionID property gets read it seems to call the getter on workflowerAPIBase although I'm making an instance of worflowerAPI.我不确定我做错了什么,但是每次读取 sessionID 属性的值时,它似乎都会调用 workflowerAPIBase 上的 getter,尽管我正在创建 worflowerAPI 的实例。

Had the same issue here (using Python 3.8):这里有同样的问题(使用 Python 3.8):

class C:
    def getx(self):
        print('getx inside C')
        return None

    x = property(getx, None)

class D(C):
    def getx(self):
        print('getx inside D')
        return None

c = C()
_ = c.x
d = D()
_ = d.x

For some reason this prints:出于某种原因,这会打印:

getx inside C
getx inside C

So the property always uses the getter of the base class.所以属性总是使用基类的getter。 However with an intermediate function that you derive you can get around this:但是,通过您派生的中间函数,您可以解决这个问题:

class C:
    def getx(self):
        self.getx_intermediate()
        return None

    def getx_intermediate(self):
        print('getx inside C')

    x = property(getx, None)

class D(C):
    def getx_intermediate(self):
        print('getx inside D')

c = C()
_ = c.x
d = D()
_ = d.x

This now prints:现在打印:

getx inside C
getx inside D

Same solution you could use for the setter.您可以为二传手使用相同的解决方案。

In Python you don't override methods, you just hide the original method by a new one in the derived class. 在Python中,您不重写方法,而只是在派生类中用新方法隐藏原始方法。 On the other side, decorators are only syntactical sugar for funcion calls. 另一方面,装饰器只是函数调用的语法糖。 So 所以

@workflowerAPIBase.sessionID.setter
def sessionID(self, value):
    ...

is short for 是短的

def set_sessionID(self, value):
    ...
sessionID = workflowerAPIBase.sessionID.setter(set_sessionID)

You set sessionID with the getter from the base class and the setter from the derived class. 您可以使用基类中的getter和派生类中的setter来设置sessionID Correct is simply: 正确很简单:

@sessionID.setter
def sessionID(self, value):
    ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM