سؤال

أي فكرة إذا كان هناك طريقة لجعل البرمجية التالية إلى العمل

class Test(object):

    def __init__(self, var):
        self.var = var

    def changeme(self):
        self = Test(3)

t = Test(1)
assert t.var == 1
t.changeme()
assert t.var == 3

هو شيء من هذا القبيل التالية آمنة للاستخدام كائنات أكثر تعقيدا (مثل django نماذج الساخنة مبادلة db دخول سبيل المثال يشير إلى)

class Test(object):

    def __init__(self, var):
        self.var = var

    def changeme(self):
        new_instance = Test(3)
        self.__dict__ = new_instance.__dict__

t = Test(1)
assert t.var == 1
t.changeme()
assert t.var == 3
هل كانت مفيدة؟

المحلول

self = Test(3) يعيد ربط الاسم المحلي self, ، مع عدم وجود آثار يمكن ملاحظتها من الخارج.

تعيين self.__dict__ (ما لم تكن تتحدث عن الحالات مع __slots__ أو من الفصول ذات النماذج غير التافهة) عادة ما تكون على ما يرام ، وكذلك self.__init__(3) لإعادة تخصيص المثيل. ومع ذلك ، أفضل أن يكون لدي طريقة محددة self.restart(3) أيّ يعرف يتم استدعاؤه على مثيل محدد بالفعل ويفعل كل ما هو مطلوب لتلبية هذه الحالة المحددة وغير العادية.

نصائح أخرى

لا و لا....

أما وقد قلت ذلك ، يمكن تغيير الدرجة, ولكن لا تفعل ذلك ايضا.

يعمل الكود السابق ، إلا أنه لن يفعل الكثير ، حيث أنه يحل محل الكائن المسمى "الذات" ضمن نطاق Changeme (). أسماء Python غير مقفلة للقيم ، فهي دائمًا تتعلق بنطاقها أو مساحة الاسم.

لفعل ما تريد ، ستحتاج إلى الوصول إلى اسم خارج الفصل ، والذي يمكنك تعيينه من الداخل:

class Test:
  def changeme(self):
    global myclass
    myclass = Test(3)

myclass = Test(2)
myclass.changeme()
print myclass # 3

هذا في الأساس يكتب فقط اسم "MyClass" للإشارة إلى المثيل الجديد. لا "الكتابة فوق" في المقام الأول كما قد تعتقد. لا تزال الحالة القديمة تعيش ، وسيتم جمع القمامة ما لم تتم الإشارة إليها في مكان آخر.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top