سؤال

أنا قادم من عالم جافا وأقرأ كتب بروس إيكلز أنماط بايثون 3 ووصفاتها وتعابيرها.

أثناء القراءة عن الفئات، يمكننا القول أنه في بايثون ليست هناك حاجة للإعلان عن متغيرات الحالة.كل ما عليك فعله هو استخدامها في المُنشئ، وهم موجودون هناك.

لذلك على سبيل المثال:

class Simple:
    def __init__(self, s):
        print("inside the simple constructor")
        self.s = s

    def show(self):
        print(self.s)

    def showMsg(self, msg):
        print(msg + ':', self.show())

إذا كان هذا صحيحا، ثم أي كائن من الدرجة Simple يمكن فقط تغيير قيمة المتغير s خارج الصف.

على سبيل المثال:

if __name__ == "__main__":
    x = Simple("constructor argument")
    x.s = "test15" # this changes the value
    x.show()
    x.showMsg("A message")

في Java، تعلمنا عن المتغيرات العامة/الخاصة/المحمية.هذه الكلمات الأساسية منطقية لأنك في بعض الأحيان تريد متغيرات في الفصل الدراسي لا يستطيع أي شخص خارج الفصل الوصول إليها.

لماذا هذا غير مطلوب في بايثون؟

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

المحلول

إنها ثقافية.في بايثون، لا تكتب إلى مثيلات الفئات الأخرى أو متغيرات الفئات.في Java، لا شيء يمنعك من فعل الشيء نفسه إذا كنت حقًا تريد - بعد كل شيء، يمكنك دائمًا تحرير مصدر الفئة نفسها لتحقيق نفس التأثير.تسقط بايثون هذا التظاهر بالأمان وتشجع المبرمجين على تحمل المسؤولية.في الممارسة العملية، وهذا يعمل بشكل جيد جدا.

إذا كنت تريد محاكاة المتغيرات الخاصة لسبب ما، فيمكنك دائمًا استخدام الملف __ البادئة من بيب 8.تشوه بايثون أسماء المتغيرات مثل __foo بحيث لا تكون مرئية بسهولة للترميز خارج الفصل الذي يحتوي عليها (على الرغم من أنك يستطيع تجاوز الأمر إذا كنت مصممًا بما فيه الكفاية، مثلك تمامًا يستطيع تجاوز وسائل حماية Java إذا كنت تعمل عليها).

وبنفس الاتفاقية، _ البادئة تعني ابتعد حتى لو لم يتم منعك فنيًا من القيام بذلك.لا يمكنك التلاعب بمتغيرات فئة أخرى تبدو كذلك __foo أو _bar.

نصائح أخرى

المتغيرات الخاصة في بايثون هي أكثر أو أقل اختراقًا:يقوم المترجم بإعادة تسمية المتغير عمدا.

class A:
    def __init__(self):
        self.__var = 123
    def printVar(self):
        print self.__var

الآن، إذا حاولت الوصول __var خارج تعريف الفئة، سوف تفشل:

 >>>x = A()
 >>>x.__var # this will return error: "A has no attribute __var"

 >>>x.printVar() # this gives back 123

ولكن يمكنك بسهولة التخلص من هذا:

 >>>x.__dict__ # this will show everything that is contained in object x
               # which in this case is something like {'_A__var' : 123}

 >>>x._A__var = 456 # you now know the masked name of private variables
 >>>x.printVar() # this gives back 456

ربما تعلم أنه يتم استدعاء الأساليب في OOP على النحو التالي: x.printVar() => A.printVar(x), ، لو A.printVar() يمكن الوصول إلى بعض الحقول في x, ، يمكن أيضًا الوصول إلى هذا الحقل الخارج A.printVar()...بعد كل شيء، يتم إنشاء الوظائف لإعادة الاستخدام، ولا توجد قوة خاصة تُمنح للبيانات الموجودة بداخلها.

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

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

و"في جافا، كنا قد تعلمناه حول المتغيرات العامة / الخاصة / محمية"

و"لماذا لا يطلب في بيثون؟"

لنفس السبب، انها ليست <م> مطلوب في جاوة.

وأنت حر في استخدام - أو عدم استخدام private وprotected

وكما مبرمجا بايثون وجافا، لقد وجدت أن private وprotected هي مفاهيم التصميم مهم جدا جدا. ولكن من الناحية العملية، في عشرات الآلاف من خطوط جافا وبيثون، لم يسبق لي ان <م> في الواقع تستخدم private أو protected.

لماذا لا؟

وهنا سؤالي "الحماية من من؟"

والمبرمجين باقي على زملائي في الفريق؟ لديهم مصدر. ماذا يعني محمية عندما يمكن تغييره؟

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

والعملاء؟ إنه عمل مقابل تأجير البرمجة (عموما). العملاء (عموما) تملك التعليمات البرمجية.

وهكذا، الذين - على وجه التحديد - أنا حمايته من

وهناك تباين المتغيرات خاصة في اتفاقية تسطير.

In [5]: class Test(object):
   ...:     def __private_method(self):
   ...:         return "Boo"
   ...:     def public_method(self):
   ...:         return self.__private_method()
   ...:     

In [6]: x = Test()

In [7]: x.public_method()
Out[7]: 'Boo'

In [8]: x.__private_method()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-8-fa17ce05d8bc> in <module>()
----> 1 x.__private_method()

AttributeError: 'Test' object has no attribute '__private_method'

وهناك بعض الاختلافات الطفيفة، ولكن من أجل نمط البرمجة النقاء الأيديولوجي، من الجيد بما فيه الكفاية.

وهناك أمثلة هناك من الديكورprivate التي تنفذ بشكل وثيق مفهوم، ولكن YMMV. يمكن القول إن واحدة أيضا كتابة defintion فئة يستخدم الفوقية

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

هنا لمعرفة المزيد عن ذلك.

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

وكما ذكر آنفا، يمكن أن تشير إلى أن متغير أو الأسلوب الخاص من خلال التقديم مع تسطير. إذا كنت لا أشعر بأن هذا يكفي، يمكنك دائما استخدام الديكور property. وإليك مثال:

class Foo:

    def __init__(self, bar):
        self._bar = bar

    @property
    def bar(self):
        """Getter for '_bar'."""
        return self._bar

وبهذه الطريقة، شخص ما أو شيء يشير bar هو في الواقع الرجوع قيمة الإرجاع للدالة bar بدلا من المتغير نفسه، وبالتالي فإنه يمكن الوصول إليها ولكن لم يتغير. ومع ذلك، إذا كان شخص ما حقا تريد، فإنها يمكن ببساطة استخدام _bar وتعيين قيمة جديدة إليها. لا توجد وسيلة مؤكدة النجاح لمنع أي شخص من الوصول إلى المتغيرات والأساليب التي ترغب في إخفاء، كما قيل مرارا وتكرارا. ومع ذلك، باستخدام property هو أوضح رسالة يمكنك إرسال ذلك لا ينبغي تحريرها متغير. ويمكن أيضا أن تستخدم property لمسارات جالبة / اضع / وصول deleter أكثر تعقيدا، كما هو موضح هنا: <لأ href = "https://docs.python.org/3/library/functions.html#property" يختلط = "نوفولو noreferrer "> https://docs.python.org/3/library/functions.html#property

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

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

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

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

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

وبالإضافة إلى ذلك، يمكن لاحظت أن مفهوم الثعبان OOP ليست مثالية، smaltalk أو روبي أقرب إلى مفهوم OOP النقي. حتى C # أو جافا هي أقرب.

وبيثون هو أداة جيدة للغاية. ولكنها مبسطة لغة OOP. مبسطة نحويا والمفاهيمية. والهدف الرئيسي من وجود الثعبان هو جعل للمطورين إمكانية لكتابة رمز من السهل قراءة مع مستوى التجريد عالية بطريقة سريعة جدا.

ورفاق عذرا ل "إحياء" الخيط، ولكن آمل أن يكون هذا سوف يساعد أحدهم:

في Python3 إذا كنت ترغب فقط في "تغليف" سمات الطبقة، مثل في جاوة، أنت فقط يمكن أن تفعل نفس الشيء مثل هذا:

class Simple:
    def __init__(self, str):
        print("inside the simple constructor")
        self.__s = str

    def show(self):
        print(self.__s)

    def showMsg(self, msg):
        print(msg + ':', self.show())

لمثيل هذه المهام:

ss = Simple("lol")
ss.show()

ملاحظة ما يلي: سوف print(ss.__s) رمي خطأ

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

ولكن لا تخافوا منه. لا يهم. أنه لا وظيفة للغاية. ؛)

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

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

ووتسطير مزدوج "__" لا يعني "المتغير الخاص". يمكنك استخدامه لتحديد المتغيرات التي هي "الطبقة المحلية" والتي لا يمكن overidden بسهولة عن طريق فرعية. ومن mangles اسم المتغيرات.

وعلى سبيل المثال:

class A(object):
    def __init__(self):
        self.__foobar = None # will be automatically mangled to self._A__foobar

class B(A):
    def __init__(self):
        self.__foobar = 1 # will be automatically mangled to self._B__foobar

ووالمهترئ اسم النفس foobar .__ تلقائيا إلى self._A__foobar في الدرجة A. في الفئة B هو المهترئ إلى self._B__foobar. وذلك في كل فئة فرعية يمكن أن تحدد __foobar متغير تلقاء نفسها دون تجاوز الديه متغير (ق). ولكن لا شيء يمنعك من الوصول إلى المتغيرات بدءا سفلية مزدوجة. ومع ذلك، اسم-تغيير اسم يمنعك من استدعاء هذه المتغيرات / طرق بالمناسبة.

وإنني أوصي بشدة لمشاهدة ريمون Hettingers الحديث "الثعابين تطوير أدوات الطبقة" من Pycon 2013 (يجب أن تكون متاحة على يوتيوب)، الذي يعطي مثالا جيدا لماذا وكيف يجب استخدامproperty و "__" - المتغيرات المثال

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