لقد سبق أن ناقشنا بالفعل الجزء المتعلق بوظيفة الفئات والكائنات، والان سنرى جزء البيانات الخاص بها. في الواقع، انها ليست سوى متغيرات عادية مرتبطة بحيزات أسماء الفئات والكائنات. هذه الأسماء صالحة ضمن سياق هذه الفئات والكائنات فقط.
وهناك نوعان من الخقول -- متغيرات الفئة، و متغيرات الكائن، والتي تصنف تبعا لما اذا كانت الفئة أو الكائن - على التوالي - تمتلكالمتغيرات.
تشتركClass متغيرات الفئةفي معنى انها تعمل من خلال جميع الكائنات (عناصر) لهذه الفئة. لا يوجد سوى نسخة من متغير الفئة، وعندما يقوم الكائن بعمل تغيير ما على متغير الفئة، ينعكس هذا التغيير في جميع الحالات الاخرى أيضا.
تختص متغيرات الكائنبكل كائن على حدة في العنصر الخاص بالفئة. وفي هذه الحالة، كل كائن له نسخة من الحقل، فمثلا هم لا يشتركون ولا يرتبطون بأي طريقة بنفس الاسم في عنصر مختلف في نفس الفئة. ورؤية مثال واحد سيجعل الأمر سهل الفهماستخدام متغيرات الفئة والكائن
مثال 11.4. استخدام متغيرات الفئة والكائن
#!/usr/bin/python # Filename: objvar.py class Person: '''Represents a person.''' population = 0 def __init__(self, name): '''Initializes the person's data.''' self.name = name print '(Initializing %s)' % self.name # When this person is created, he/she # adds to the population Person.population += 1 def __del__(self): '''I am dying.''' print '%s says bye.' % self.name Person.population -= 1 if Person.population == 0: print 'I am the last one.' else: print 'There are still %d people left.' % Person.population def sayHi(self): '''Greeting by the person. Really, that's all it does.''' print 'Hi, my name is %s.' % self.name def howMany(self): '''Prints the current population.''' if Person.population == 1: print 'I am the only person here.' else: print 'We have %d persons here.' % Person.population swaroop = Person('Swaroop') swaroop.sayHi() swaroop.howMany() kalam = Person('Abdul Kalam') kalam.sayHi() kalam.howMany() swaroop.sayHi() swaroop.howMany()
$ python objvar.py (Initializing Swaroop) Hi, my name is Swaroop. I am the only person here. (Initializing Abdul Kalam) Hi, my name is Abdul Kalam. We have 2 persons here. Hi, my name is Swaroop. We have 2 persons here. Abdul Kalam says bye. There are still 1 people left. Swaroop says bye. I am the last one.
هذا مثال طويل ولكنه يساعد في تبيين طبيعة متغيرات الفئة والكائن؛ وهنا population تنتمي إلى الفئة Person، ولذا تعتبر متغيرا للفئة. والمتغير name ينتمي إلى الكائن ( وهو مسند باستخدام self) وبالتالي هو متغير للكائن.
وهكذا نشير إلى متغير الفئة populationكـ Person.populationوليس كـ self.population. لاحظ أن متغير كائن يحمل نفس اسم متغير الفئة سوف يخفي متغير الفئة ! ونحن نشير إلى متغير الكائن nameباستخدام self.name في الطرق الخاصة بالكائن .تذكر أن هناك اختلاف بسيط بين متغيرات الفئة ومتغيرات الكائن .
لاحظْ بأنّ طريقة __init__تُستَعملُ لعمل تهيئة للعنصر Person مَع name. وفي هذه الطريقةِ، نزيد عدد population بمقدار 1 حيث نحصل على Person واحد مضافا. كذلك نلاحظ أن قيم self.nameتحدد لكل كائن يشير إلى طبيعة متغيرات الكائن.
تذكر أنه يجب أن تشير إلى المتغيرات والطرق الخاصة بنفس الكائن باستخدام المتغير self وفقط. وذلك يدعى attribute reference.
في هذا البرنامج نرى أيضا استخدام docstrings للفئات وكذلك الطرق. يمكننا الوصول إلى class docstring في وقت التشغيل باستخدام Person.__doc__ والطريقة docstring كـ Person.sayHi.__doc__
وهناك طريقة أخرى تشبه __init__ مثل __del__،التي تستدعى عندما يوشك كائن ما على الموت .ولا يمكن استخدامه بعد ذلك، وستتم إعادته إلى النظام لإعادة استعمال هذا الجزء من الذاكرة. وفي هذه الطريقة نقوم ببساطة بإنقاص حساب ال Person.population بمقدار 1.
طريقة__del__ تعمل حين لا يكون الكائن مستخدما، وليس هناك ضمان متىستعمل هذه الطريقة. وإذا أردت عمل ذلك بوضوح عليك فقط أن تستخدم إفادة delالتي استعملناها في الأمثلة السابقة.
جميع عناصر الفئة(إضافة إلى عناصر البيانات) تعتبر عموميةوجميع الطرق تعتبر تخيلية في بيثون.
وهناك استثناء واحد؛ إذا كنت تستخدم عناصر البيانات مع الأسماء باستخدامبادئة الشرطتين السفليتين مثل __privatevar؛تستخدم بيثون صقل الاسم بفاعلية ليجعل لها قيمة منفردة.
هكذا فإن الاتفاقية المتبعة هي أن كل متغير يستعمل فقط داخل الفئة أو الكائن يجب أن يصبح بشرطة سفلية، وجميع الأسماء الأخرى عامة-public ويمكن أن تستخدم من قبل أي فئات/كائنات .تذكر أن هذه اتفاقية فحسب وليست إجبارية من بيثون (ما عدا بادئة الشرطة السفلية المزدوجة).
لاحظ أيضاً أن الطريقة __del__ تماثل مفهوم destructor.