سؤال

ما هو الفرق بين type(obj) و obj.__class__?هل هناك إمكانية type(obj) is not obj.__class__?

أريد أن أكتب وظيفة يعمل بشكل عام على الموردة الكائنات باستخدام القيمة الافتراضية 1 في نفس نوع آخر المعلمة.والتي الاختلاف ، #1 أو #2 أدناه ، سوف تفعل الشيء الصحيح ؟

def f(a, b=None):
  if b is None:
    b = type(a)(1) # #1
    b = a.__class__(1) # #2
هل كانت مفيدة؟

المحلول

وtype(obj) وtype.__class__ لا تتصرف نفسها لفئات النمط القديم:

>>> class a(object):
...     pass
...
>>> class b(a):
...     pass
...
>>> class c:
...     pass
...
>>> ai=a()
>>> bi=b()
>>> ci=c()
>>> type(ai) is ai.__class__
True
>>> type(bi) is bi.__class__
True
>>> type(ci) is ci.__class__
False

نصائح أخرى

هذا هو السؤال القديم ، ولكن أيا من الإجابات يبدو أن أذكر ذلك.في الحالة العامة ، هو ممكن جديد-نمط الطبقة إلى قيم مختلفة type(instance) و instance.__class__:

class ClassA(object):
    def display(self):
        print("ClassA")

class ClassB(object):
    __class__ = ClassA

    def display(self):
        print("ClassB")

instance = ClassB()

print(type(instance))
print(instance.__class__)
instance.display()

الإخراج:

<class '__main__.ClassB'>
<class '__main__.ClassA'>
ClassB

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

والطبقات الطراز القديم هي المشكلة، تنفس الصعداء:

>>> class old: pass
... 
>>> x=old()
>>> type(x)
<type 'instance'>
>>> x.__class__
<class __main__.old at 0x6a150>
>>> 

وليست مشكلة في بيثون 3 منذ كافة فئات هي نمط جديد الآن، -)

في بايثون 2، والطبقة هي الطراز الجديد إلا إذا كان يرث من فئة أخرى جديدة على غرار (بما في ذلك object ومختلف المدمج في أنواع مثل dict، list، set، ...) يحدد أو ضمنا أو صراحة __metaclass__ إلى type.

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