سؤال

لذلك، ألعب مع الديكور في بيثون 2.6، وأواجه بعض المشاكل في الحصول عليها. هنا هو ملف الفصل الخاص بي:

class testDec:

    @property
    def x(self): 
        print 'called getter'
        return self._x

    @x.setter
    def x(self, value): 
        print 'called setter'
        self._x = value

ما اعتقدت أن هذا يعني هو علاج x مثل الممتلكات، ولكن استدعاء هذه الوظائف على الحصول على وتعيين. لذلك، قمت بإطلاق الخمول وفحصها:

>>> from testDec import testDec
from testDec import testDec
>>> t = testDec()
t = testDec()
>>> t.x
t.x
called getter
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "testDec.py", line 18, in x
    return self._x
AttributeError: testDec instance has no attribute '_x'
>>> t.x = 5
t.x = 5
>>> t.x
t.x
5

من الواضح أن الاتصالات الأولى تعمل كما هو متوقع، لأنني أسمي Getter، وليس هناك قيمة افتراضية، وفشلها. حسنا، جيد، أنا أفهم. ومع ذلك، دعوة لتعيين t.x = 5 يبدو أن تخلق خاصية جديدة x, ، والآن لا يعمل Getter!

ماذا ينقصني؟

هل كانت مفيدة؟

المحلول

يبدو أنك تستخدم دروس الكلاسيكية القديمة في بيثون 2. من أجل الخصائص للعمل بشكل صحيح تحتاج إلى استخدام فصول جديدة بدلا من ذلك (في بيثون 2 يجب عليك ورث من object). فقط أعلن فصلك MyClass(object):

class testDec(object):

    @property
    def x(self): 
        print 'called getter'
        return self._x

    @x.setter
    def x(self, value): 
        print 'called setter'
        self._x = value

إنها تعمل:

>>> k = testDec()
>>> k.x
called getter
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/devel/class_test.py", line 6, in x
    return self._x
AttributeError: 'testDec' object has no attribute '_x'
>>> k.x = 5
called setter
>>> k.x
called getter
5
>>> 

تفاصيل أخرى قد تسبب مشاكل في أن كلا الطريقتين بحاجة إلى نفس اسم الممتلكات للعمل. إذا حددت STERTER باسم مختلف مثل هذا لن يعمل:

@x.setter
def x_setter(self, value):
    ...

وأشيء آخر ليس من السهل تماما في البداية، هو الترتيب: Getter يجب أن يتم تعريفه أولا. وبعد إذا حددت STERTER أولا، فستحصل name 'x' is not defined خطأ.

نصائح أخرى

مجرد ملاحظة للأشخاص الآخرين الذين تتعثرون هنا يبحثون عن هذا الاستثناء: كلاهما يحتاج إلى نفس الاسم. تسمية الأساليب على النحو التالي ستؤدي إلى استثناء:

@property
def x(self): pass

@x.setter
def x_setter(self, value): pass

بدلا من ذلك إعطاء كلتا الطريقتين نفس الاسم

@property
def x(self): pass

@x.setter
def x(self, value): pass

من المهم أيضا أن نلاحظ أن أمر المسائل الإعلانية. يجب تعريف Getter قبل STERTER في الملف وإلا فسوف تحصل عليه NameError: name 'x' is not defined

تحتاج إلى استخدام فئات نمط جديد تقوم به عن طريق اشتقاق فصلك من كائن:

class testDec(object):
   ....

ثم يجب أن تعمل.

في حالة وجود أي شخص هنا من Google، بالإضافة إلى الإجابات المذكورة أعلاه، أود أن أضيف أن هذا يحتاج إلى انتباه دقيق عند استدعاء STERTER من __init__ طريقة الفصل الخاص بك بناء على هذه الإجابةخاصة:

class testDec(object):                                                                                                                                            

    def __init__(self, value):
        print 'We are in __init__'
        self.x = value # Will call the setter. Note just x here
        #self._x = value # Will not call the setter

    @property
    def x(self):
        print 'called getter'
        return self._x # Note the _x here

    @x.setter
    def x(self, value): 
        print 'called setter'
        self._x = value # Note the _x here

t = testDec(17)
print t.x 

Output:
We are in __init__
called setter
called getter
17
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top