ما هو الفرق بين النمط القديم و الجديد على غرار دروس في الثعبان ؟

StackOverflow https://stackoverflow.com/questions/54867

سؤال

ما هو الفرق بين النمط القديم و الجديد على غرار دروس في الثعبان ؟ متى يجب استخدام واحدة أو أخرى ؟

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

المحلول

من http://docs.python.org/2/reference/datamodel.html#new-style-and-classic-classes :

حتى الثعبان 2.1, الطراز القديم فصول فقط نكهة المتاحة للمستخدم.

مفهوم (الطراز القديم) فئة لا علاقة لها بمفهوم النوع:إذا x مثيل من الطراز القديم فئة ، ثم x.__class__ يعين فئة من x, ولكن type(x) دائما <type 'instance'>.

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

جديدة على غرار الطبقات أدخلت في بيثون 2.2 لتوحيد مفاهيم الفئة ونوع.جديد على غرار الطبقة هو ببساطة نوع معرف من قبل المستخدم, لا أكثر ولا أقل.

إذا كان x مثيل جديد على غرار فئة ، ثم type(x) عادة نفس x.__class__ (على الرغم من أن هذه ليست مضمونة – a نمط جديد من الدرجة سبيل المثال يسمح تجاوز القيمة التي تم إرجاعها بالنسبة x.__class__).

الرئيسية الدافع جديدة على غرار الطبقات هو توفير موحد نموذج كائن مع التعريف الكامل-نموذج.

كما أن لديها عدد من الفوائد الفورية ، مثل القدرة على فرعية معظم المدمج في أنواع ، أو إدخال "واصف", التي تتيح احتساب خصائص.

لأسباب التوافق ، ما زالت الطبقات الطراز القديم بشكل افتراضي.

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

سلوك جديد على غرار الطبقات يختلف من الطراز القديم دروس في عدد من التفاصيل الهامة بالإضافة إلى ما هو نوع العوائد.

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

بيثون 3 فقط جديدة على غرار الطبقات.

لا يهم إذا كنت فرعية من object أو لا ، دروس جديدة على غرار في بيثون 3.

نصائح أخرى

إعلان الحكيم:

جديدة على غرار الطبقات ترث من وجوه ، أو من أخرى جديدة على غرار فئة.

class NewStyleClass(object):
    pass

class AnotherNewStyleClass(NewStyleClass):
    pass

على الطراز القديم الصفوف لا.

class OldStyleClass():
    pass

أهم التغييرات في السلوك بين القديم والجديد نمط الطبقات

  • سوبر وأضاف
  • MRO تغير (الموضح أدناه)
  • الواصفات وأضاف
  • نمط جديد من فئة الأشياء لا يمكن رفع ما لم تكن مستمدة من Exception (المثال أدناه)
  • __slots__ وأضاف

MRO (القرار طريقة الترتيب) تغيرت

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

السؤال هو ترتيب الصفات (التي تشمل أساليب الأعضاء المتغيرات) يتم البحث عنها في العديد من الميراث.

الكلاسيكية الطبقات هل عمق البحث الأول من اليسار إلى اليمين.وقف على المباراة الأولى.ليس لديهم __mro__ السمة.

class C: i = 0
class C1(C): pass
class C2(C): i = 2
class C12(C1, C2): pass
class C21(C2, C1): pass

assert C12().i == 0
assert C21().i == 2

try:
    C12.__mro__
except AttributeError:
    pass
else:
    assert False

جديدة على غرار الطبقات MRO أكثر تعقيدا لتجميع واحد الجملة الإنجليزية.هو شرح بالتفصيل هنا.واحدة من خصائصه أن قاعدة الطبقة هو فقط البحث عن كل الفئات المشتقة تم.لديهم __mro__ السمة التي تظهر في ترتيب البحث.

class C(object): i = 0
class C1(C): pass
class C2(C): i = 2
class C12(C1, C2): pass
class C21(C2, C1): pass

assert C12().i == 2
assert C21().i == 2

assert C12.__mro__ == (C12, C1, C2, C, object)
assert C21.__mro__ == (C21, C2, C1, C, object)

نمط جديد من فئة الأشياء لا يمكن رفع ما لم تكن مستمدة من Exception

حول بايثون 2.5 العديد من الفئات التي يمكن أن تثار حول بيثون 2.6 هذا إزالتها.على الثعبان 2.7.3:

# OK, old:
class Old: pass
try:
    raise Old()
except Old:
    pass
else:
    assert False

# TypeError, new not derived from `Exception`.
class New(object): pass
try:
    raise New()
except TypeError:
    pass
else:
    assert False

# OK, derived from `Exception`.
class New(Exception): pass
try:
    raise New()
except New:
    pass
else:
    assert False

# `'str'` is a new style object, so you can't raise it:
try:
    raise 'str'
except TypeError:
    pass
else:
    assert False

النمط القديم فئات لا تزال هامشية أسرع من أجل البحث سمة.هذه ليست عادة مهمة ، ولكن قد تكون مفيدة في الأداء الحساسة بيثون 2.x code:

In [3]: class A:
   ...:     def __init__(self):
   ...:         self.a = 'hi there'
   ...: 

In [4]: class B(object):
   ...:     def __init__(self):
   ...:         self.a = 'hi there'
   ...: 

In [6]: aobj = A()
In [7]: bobj = B()

In [8]: %timeit aobj.a
10000000 loops, best of 3: 78.7 ns per loop

In [10]: %timeit bobj.a
10000000 loops, best of 3: 86.9 ns per loop

غيدو كتب القصة من الداخل على غرار الطبقات, حقا مقالة رائعة حول نمط جديد و قديم الطراز الدرجة في بيثون.

بيثون 3 الجديدة فقط على غرار الدرجة ، حتى لو كنت أكتب القديمة الدرجة ، ضمنا المستمدة من object.

جديدة على غرار الطبقات لديها بعض الميزات المتقدمة من نقص في الطراز القديم الطبقات ، مثل super الجديد C3 mro, بعض طرق سحرية ، إلخ.

وهنا عملي جدا, True/False الفرق.الفرق الوحيد بين النسختين من التعليمة البرمجية التالية في الإصدار الثاني الشخص يرث من وجوه.بخلاف ذلك النسختين متطابقة ، ولكن مع نتائج مختلفة :

1) الطراز القديم الطبقات

class Person():
    _names_cache = {}
    def __init__(self,name):
        self.name = name
    def __new__(cls,name):
        return cls._names_cache.setdefault(name,object.__new__(cls,name))

ahmed1 = Person("Ahmed")
ahmed2 = Person("Ahmed")
print ahmed1 is ahmed2
print ahmed1
print ahmed2


>>> False
<__main__.Person instance at 0xb74acf8c>
<__main__.Person instance at 0xb74ac6cc>
>>>

2) نمط جديد دروس

class Person(object):
    _names_cache = {}
    def __init__(self,name):
        self.name = name
    def __new__(cls,name):
        return cls._names_cache.setdefault(name,object.__new__(cls,name))

ahmed1 = Person("Ahmed")
ahmed2 = Person("Ahmed")
print ahmed2 is ahmed1
print ahmed1
print ahmed2

>>> True
<__main__.Person object at 0xb74ac66c>
<__main__.Person object at 0xb74ac66c>
>>>

جديدة على غرار الطبقات ترث من object و يجب أن تكون مكتوبة في بيثون 2.2 فصاعدا (أي class Classname(object): بدلا من class Classname:).جوهر التغيير هو توحيد أنواع و فئات و جميلة آثار جانبية من هذا هو أنه يسمح لك أن ترث من المدمج في أنواع.

قراءة descrintro للحصول على مزيد من التفاصيل.

نمط جديد من فصول قد تستخدم super(Foo, self) حيث Foo هي فئة ، self هو على سبيل المثال.

super(type[, object-or-type])

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

و في بيثون 3.× يمكنك ببساطة استخدام super() داخل الصف مع المعلمات.

أو بدلا من ذلك ، يجب عليك دائما استخدام جديدة على غرار الطبقات ، إلا إذا لديك التعليمات البرمجية التي تحتاج إلى العمل مع إصدارات بيثون أكبر من 2.2.

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