سؤال

كيف يمكنني جعل الأساليب وأعضاء البيانات خاصة في بايثون؟أم أن بايثون لا تدعم الأعضاء الخاصين؟

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

المحلول

9.6.المتغيرات الخاصة

متغيرات مثيل "خاصة" لا يمكن الوصول إليها إلا من داخل كائن ، لا توجد في بيثون.ومع ذلك ، هناك اتفاقية يتبعها معظم كود بيثون:اسم بادئة مع السطح السفلي (على سبيل المثاليجب معاملة _spam) كجزء غير عام من واجهة برمجة التطبيقات (سواء كانت دالة أو طريقة أو عضو في البيانات).يجب اعتباره تفاصيل التنفيذ ويخضع للتغيير دون إشعار.

نظرًا لوجود حالة استخدام صالحة للأعضاء الفائزين (أي لتجنب اشتباكات أسماء الأسماء مع الأسماء المحددة بواسطة الفئات الفرعية) ، هناك دعم محدود لمثل هذه الآلية ، تسمى اسم Millgling.يتم استبدال أي معرف للنموذج __spam (على الأقل اثنين من السدود الرائدة ، على الأكثر ترتيبًا واحدًا) _classname__spam, ، حيث يكون اسم ClassName هو اسم الفصل الحالي مع تجريده (S).يتم هذا الانقلاب دون النظر إلى الموضع النحوي للمعرف ، طالما يحدث ضمن تعريف الفئة.

لذا، على سبيل المثال,

class Test:
    def __private_symbol(self):
        pass
    def normal_symbol(self):
        pass

print dir(Test)

سوف يخرج:

['_Test__private_symbol', 
'__doc__', 
'__module__', 
'normal_symbol']

__private_symbol ينبغي اعتبارها طريقة خاصة، ولكن لا يزال من الممكن الوصول إليها من خلال _Test__private_symbol.

نصائح أخرى

والأجوبة أخرى توفر التفاصيل التقنية. أود التأكيد على الاختلاف في الفلسفة بين بيثون من جهة ولغات مثل C ++ / جافا (والتي أفترض أنك على دراية بناء على سؤالك).

والموقف العام في بايثون (بيرل ولهذه المسألة) هو أن "الخصوصية" سمة هي طلب للمبرمج بدلا من الأسلاك الشائكة من قبل مترجم / مترجم. وتتلخص فكرة جيدة في هذا البريد وغالبا ما يشار إلى كما قال "نحن جميع البالغين بالتراضي" لأنه "يفترض" أن مبرمج يكفي المسؤولة لعدم التدخل في الدواخل. على أحرف الرائدة بمثابة رسالة مهذبا قائلا إن السمة الداخلية.

ومن ناحية أخرى، إذا كنت لا تريد الوصول إلى الداخلية لبعض التطبيقات (أ الأمثلة البارزة على مولدات الوثائق مثل pydoc)، أنت حر في القيام بذلك. المسؤولية تقع عليك كمبرمج لمعرفة ما تفعلونه وتفعل ذلك بشكل صحيح بدلا من التركيز على اللغة لإجبار تفعله لأشياء <م> انها الطريق.

لا يوجد private لأي آليات أخرى لحماية الوصول في بايثون.هناك اتفاقية موثقة في دليل أسلوب بايثون للإشارة إلى مستخدمي صفك أنه لا ينبغي لهم الوصول إلى سمة معينة.

  • _single_leading_underscore:مؤشر "الاستخدام الداخلي" ضعيف.على سبيل المثال from M import * لا يستورد كائنات يبدأ اسمها بشرطة سفلية.

  • Single_trailing_underscore_:تُستخدم تقليديًا لتجنب التعارضات مع كلمة Python الأساسية، على سبيل المثال. Tkinter.Toplevel(master, class_='ClassName')

  • __double_leading_underscore:عند تسمية سمة فئة، يتم استدعاء تغيير الاسم (داخل الفئة FooBar، يصبح __boo _FooBar__boo؛انظر أدناه).

إذا كان اسم وظيفة Python أو طريقة الفئة أو السمة يبدأ بـ (ولكن لا ينتهي) اثنين من السطحين ، فهو خاص ؛ كل شيء آخر عام.لا يوجد لدى Python مفهوم طرق الطبقة المحمية (لا يمكن الوصول إليها إلا في فصول الدرجة الخاصة بهم والأحفاد).أساليب الفصل إما خاصة (يمكن الوصول إليها فقط في فئتها الخاصة) أو الجمهور (يمكن الوصول إليها من أي مكان).

الغوص في بايثون

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

class Person(object):

    def __priva(self):
        print "I am Private"

    def publ(self):
        print " I am public"

    def callpriva(self):
        self.__priva()

والآن عندما وسيتم تنفيذ:

>>> p = Person()
>>> p.publ()
 I am public
>>> p.__priva()
Traceback (most recent call last):
  File "", line 1, in 
    p.__priva()
AttributeError: 'Person' object has no attribute '__priva'
​#Explanation   : You can see  here we are not able to fetch that private method directly.
>>> p.callpriva()
I am Private
#​Explanation  : Here we can access private method inside class​

وثم كيف يمكن للشخص أن الوصول إلى هذا المتغير ؟؟؟
يمكنك أن تفعل مثل:

>>>p._Person__priva
I am Private

ونجاح باهر، في الواقع إذا الثعبان هو الحصول على أي متغير بدءا تسطير مزدوج و"ترجم" عن طريق إضافة تسطير واحد واسم الفئة إلى البداية:

<قوية> ملاحظة: إذا كنت لا تريد هذا الاسم تغيير ولكنك لا تزال ترغب في إرسال إشارة لكائنات أخرى للبقاء بعيدا، يمكنك استخدام واحدة أسماء تسطير الأولية مع تسطير الأولي ليسوا المستوردة مع واردات المميزة بنجمة (من وحدة استيراد *)
مثال:

#test.py
def hello():
    print "hello"
def _hello():
    print "Hello private"

#----------------------
#test2.py
from test import *
print hello()
print _hello()

والانتاج ->

hello
Traceback (most recent call last):
  File "", line 1, in 
NameError: name '_hello' is not defined

والآن إذا سنطالب _hello يدويا.

#test2.py
from test import _hello , hello
print hello()
print _hello()

والانتاج ->

hello
hello private

وأخيرا: بيثون لا يملك في الواقع دعما الخصوصية يعادل، على الرغم من واحد ويشدد الأولية مزدوجة لا إلى حد ما تعطيك مستويين للخصوصية

وهذا عمل القوة:

import sys, functools

def private(member):
    @functools.wraps(member)
    def wrapper(*function_args):
      myself = member.__name__
      caller = sys._getframe(1).f_code.co_name
      if (not caller in dir(function_args[0]) and not caller is myself):
         raise Exception("%s called by %s is private"%(myself,caller))
      return member(*function_args)
    return wrapper

class test:
   def public_method(self):
      print('public method called')

   @private
   def private_method(self):
      print('private method called')

t = test()
t.public_method()
t.private_method()

وهذا هو كيندا ل س ن ز الجواب ولكن اعتقد انه يحصل على جذر المشكلة الحقيقية هنا - نطاق الرؤية. مجرد تعليق في هناك بينما أنا مستنقع من خلال هذا!

وببساطة استيراد وحدة نمطية ليس من الضروري أن يعطي بالضرورة وصول مطور التطبيق لجميع الطبقات، أو الأساليب؛ إذا كنت لا يمكن أن نرى في الواقع شفرة المصدر وحدة كيف لي ان اعرف ما هو متاح؟ بعض واحد (أو بعض الشيء) أن تقول لي ما يمكنني القيام به وشرح كيفية استخدام هذه الميزات أنا سمحت لاستخدام، وإلا فإن كل شيء لا طائل منه بالنسبة لي.

ويتم عرض هذه المجردات على مستوى أعلى النامية على أساس الفئات وأساليب عبر وحدات المستوردة الأساسية مع وثيقة مواصفات - لا شفرة المصدر الفعلي.

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

ويجب عدم تغير وحدة نمطية دون تغيير أول وثيقة المواصفات الكامنة وراءه، والتي قد تتطلب مراجعة / الموافقة في بعض المنظمات السابقة إلى تغيير التعليمات البرمجية.

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

وبعد ذلك أبدأ الترميز من خلال كتابة مختلف الطبقات وطرق ولكن دون الهيئات وظيفية - البيانات المطبوعة فقط فارغة مثل "الطباعة ()" - ما يكفي للسماح للوحدة لتجميع بدون أخطاء في بناء الجملة. عندما اكتمال هذه الخطوة I تجميع الانتهاء خالية حدة - وهذا هو بلدي المواصفات. لو كنت تعمل على فريق المشروع، وأود أن تقديم هذه المواصفات / واجهة للمراجعة والتعليق قبل المتابعة مع بلورة الجسم.

وأنا خارج الجسد جثث طريقة كل واحد في وقت وتجميع وفقا لذلك، وضمان ثابتة أخطاء في بناء الجملة فورا على ذبابة. وهذا أيضا هو الوقت المناسب للبدء في كتابة قسم التنفيذ المؤقت "الرئيسي" في الجزء السفلي لاختبار كل طريقة وأنت رمز ذلك. عندما الترميز / اختبار كاملة، كافة التعليمات البرمجية الاختبار علق بها حتى كنت في حاجة إليها مرة أخرى يجب أن تصبح التحديثات اللازمة.

في فريق التطوير في العالم الحقيقي، سوف تظهر كتلة تعليق المواصفات أيضا في مكتبة مراقبة وثيقة، ولكن تلك قصة أخرى. وهذه النقطة هي: لكم، والعميل وحدة، انظر فقط هذه المواصفات وليس شفرة المصدر

وPS: قبل فترة طويلة من بداية الوقت، عملت في المجتمع الفضاء الدفاع وفعلنا بعض الاشياء باردة جميلة، ولكن أشياء مثل خوارزميات الملكية ومنطق السيطرة النظم الحساسة وقفز بإحكام ومشفرة في السوبر المخادع مكتبات البرامج آمنة. تمكنا من الوصول إلى وحدة / واجهات حزمة ولكن ليس على جثث الاسود التنفيذ. كان هناك أداة إدارة الوثائق التي تعالج جميع التصاميم على مستوى النظام، والمواصفات البرمجيات، وشفرة المصدر وسجلات الاختبار - تم مزامنته كل ذلك معا. وكانت الحكومة متطلبات البرامج معايير صارمة لضمان الجودة. يتذكر أحد لغة تسمى "آدا"؟ هذه هي الطريقة عمري!

ويمكنني استخدام بايثون 2.7 و 3.5. لقد كتبت هذا الرمز:

class MyOBject(object):
    def __init__(self):
        self.__private_field = 10


my_object = MyOBject()
print(my_object.__private_field)

وركض وحصلت على:

<اقتباس فقرة>   

وAttributeError: الكائن 'MyOBject "لا يوجد لديه السمة' __private_field '

ويرجى الاطلاع على: https://www.tutorialsteacher.com/python/ خاصة ومحمية وصول-المعدلات في والثعبان

وإذا كنت تريد أن تجعل من وسائل أو أعضاء البيانات الخاصة في بيثون، استخدام __setattr __

class Number:
    def __init__(self,value):
        self.my_private = value

    def __setattr__(self, my_private, value):
        # the default behavior
        # self.__dict__[my_private] = value
        raise Exception("can't access private member-my_private")


def main():
    n = Number(2)
    print(n.my_private)

if __name__ == '__main__': 
    main()
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top