سؤال

لقد حددت أ Vector الفصل الذي يحتوي على ثلاثة متغيرات الممتلكات: x, y و z. يجب أن تكون الإحداثيات أرقامًا حقيقية ، ولكن لا يوجد شيء لمنع واحد من القيام بما يلي:

>>> v = Vector(8, 7.3, -1)
>>> v.x = "foo"
>>> v.x
"foo"

يمكنني تنفيذ "نوع السلامة" مثل هذا:

import numbers

class Vector:
    def __init__(self, x, y, z):
        self.setposition(x, y, z)

    def setposition(self, x, y, z):
        for i in (x, y, z):
            if not isinstance(i, numbers.Real):
                raise TypeError("Real coordinates only")

        self.__x = x
        self.__y = y
        self.__z = z

    @property
    def x(self):
        return self.__x

    @property
    def y(self):
        return self.__y

    @property
    def z(self):
        return self.__z

... لكن هذا يبدو غير متجانس.

اقتراحات؟

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

المحلول

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

>>> 3.0 / 'abc'
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: unsupported operand type(s) for /: 'float' and 'str'

نصائح أخرى

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

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

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

إذا كنت تريد حلًا أكثر بيثونيًا - يمكنك استخدام مستقديات العقارات مثل:

@x.setter
def x(self, value):
    assert isinstance(value, numbers.Real)
    self.__x = value

ستتم إزالة بيان التأكيد عند تعطيل تصحيح الأخطاء أو تمكين وضع التحسين.

بدلاً من ذلك ، يمكنك فرض value إلى نقطة عائمة في Setter. سيؤدي ذلك إلى رفع استثناء إذا كان النوع/القيمة غير قابل للتحويل:

@x.setter
def x(self, value):
    self.__x = float(value)

ولكن لا يوجد شيء يمنع واحد من فعل ما يلي:

أعتقد أن محاولة منع شخص ما من فعل شيء من هذا القبيل هو un-pythonic. إذا كان عليك ذلك ، فعليك التحقق من السلامة نوع أثناء أي عمليات قد تقوم باستخدامها Vector, ، فى رايى.

لاقتباس GVR:

نحن جميعا بالغين.

بعد كل شيء. انظر الى هذا سؤال وإجاباتها لمزيد من المعلومات.

أنا متأكد من أن Pythonistas أكثر خبرة هنا يمكن أن تعطيك إجابات أفضل.

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

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

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

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

لكن بما فيه الكفاية من ذلك ، أنا بالفعل متسلل.

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