2015-09-09 18 views
10

Kolaylık sağlamak için paketlediğim birkaç dosyayı kapsayan python kodum var: my_package dizininin altındaki aşağıdaki 3 dosyayla sonlandırıyorum:autoreload ve package neden TypeError: super (tür, obj): nesne tür veya alt türü olmalıdır

__init__.py 

içeriği:

from file1 import * 
from file2 import * 

file1.py içeriği:

class Base(object): 
    pass 

file2.p y içeriği:

from file1 import Base 
class Derived(Base): 
    def __init__(self): 
     return super(Derived, self).__init__() 
Sonra ipython yürütmek

: Şimdiye kadar

>>>%autoreload 2 
>>>import my_package 
>>>t = my_package.Derived() 

çok iyi. Ama sonra ben dosya2.py'de değişiklik yapıyorum, kukla özelliği ekleyerek söyleyin. Şimdi yürütmek zaman: Ben ipython konsolunu yeniden başlatana kadar

>>>t = my_package.Derived() 
>>>  2 class Derived(Base): 
>>>  3  def __init__(self): 
>>>----> 4   return super(Derived, self).__init__() 
>>>  5 
>>>  6 dumm = 'asdf' 
>>> 
>>>TypeError: super(type, obj): obj must be an instance or subtype of type 

Bu uzağa gitmez. Neden otomatik olarak doğru şekilde ilgilenmiyor? Temel ve Türetilmiş'i paket yerine tek bir modül dosyasına koyarsam her şey çalışır.

cevap

6

IPython kullanıcısı değilim, bu yüzden neler olduğunu tam olarak söyleyemem, ancak bu, 'u __init__.py dosyanızda kullanmanın bir belirtisidir.

Eğer package.Derived kullanarak Derived sınıfının bir örneğini oluştururken

, sınıfın en son sürümünü almıyorsanız, ancak paketin ilk yüklendiğinde andaki güncel eski sürümü ve from file2 import * beyanı çalıştırıldı . Modül kodunu değiştirdiğinizde ve IPython yeniden yüklendiğinde, bu package.file2.Derived'u değiştirdi, ancak package.Derived'u değiştirmedi.

Ancak, sınıfın eski sürümü, modülünün ad alanı için bir referansı hala vardır ve super numaralı çağrıda kendini ismine bakmaya çalıştığında, bunun yerine sınıfın daha yeni sürümünü bulur. Bu nedenle, iki Derived sınıfı aynı olmadığından bir hata alırsınız.

Doğrudan package.file2.Derived numaralı telefona eriştiyseniz, bu sorunun önüne geçebilirsiniz. Bu, her zaman super çağrıları ile ilgili herhangi bir sorun olmaması gereken sınıfın geçerli sürümüne ulaşacaktır. Modülü değiştirmeden önce oluşturulan sınıfın örnekleri varsa, hala sorunlarınız olabilir (ancak bu muhtemelen çok şaşırtıcı değil).

+2

Bu mantıklıdır. "Dosya2 içe aktarma türetme" yerine * kullanmayı denedim, ancak maalesef bunu düzeltemedi. Otoreload'ın bu paketi anlayamadığı gariptir.Derived güncellenmelidir. – Leo

+0

@Leo B bir '__init __. Py' dosyası içeriyorsa, A.B içe aktarma C''sini kullanırken hata görünüyor. Bu beni çok rahatsız ediyor. – Edityouprofile

İlgili konular