Pertanyaan Cara mengimpor kelas yang ditentukan dalam __init__.py


Saya mencoba mengatur beberapa modul untuk saya sendiri. Saya memiliki sesuatu seperti ini:

lib/
  __init__.py
  settings.py
  foo/
    __init__.py
    someobject.py
  bar/
    __init__.py
    somethingelse.py

Di lib/__init__.pySaya ingin mendefinisikan beberapa kelas yang akan digunakan jika saya mengimpor lib. Namun, saya tidak bisa mengetahuinya tanpa memisahkan kelas ke dalam file, dan mengimpornya__init__.py.

Daripada berkata:

    lib/
      __init__.py
      settings.py
      helperclass.py
      foo/
        __init__.py
        someobject.py
      bar/
        __init__.py
        somethingelse.py

from lib.settings import Values
from lib.helperclass import Helper

Saya menginginkan sesuatu seperti ini:

    lib/
      __init__.py  #Helper defined in this file
      settings.py
      foo/
        __init__.py
        someobject.py
      bar/
        __init__.py
        somethingelse.py

from lib.settings import Values
from lib import Helper

Apakah mungkin, atau apakah saya harus memisahkan kelas ke dalam file lain?

EDIT

Oke, jika saya mengimpor lib dari skrip lain, saya dapat mengakses kelas Helper. Bagaimana saya dapat mengakses kelas Helper dari settings.py?

Contoh sini mendeskripsikan Referensi Paket-dalam. Saya mengutip "submodul sering perlu merujuk satu sama lain". Dalam kasus saya, lib.settings.py membutuhkan Helper dan lib.foo.someobject membutuhkan akses ke Helper, jadi di mana saya harus mendefinisikan kelas Helper?


76
2018-02-24 17:35


asal


Jawaban:


  1. 'lib/direktori induk harus ada sys.path.

  2. Anda 'lib/__init__.py'Mungkin terlihat seperti ini:

    from . import settings # or just 'import settings' on old Python versions
    class Helper(object):
          pass
    

Maka contoh berikut harus berfungsi:

from lib.settings import Values
from lib import Helper

Jawaban untuk versi pertanyaan yang diedit:

__init__.py mendefinisikan bagaimana paket Anda terlihat dari luar. Jika perlu digunakan Helper di settings.py kemudian definisikan Helper dalam file yang berbeda misalnya, 'lib/helper.py'.

.
| `- import_submodule.py
    `- lib
    | - __init__.py
    | - foo
    | | - __init__.py
    | `- someobject.py
    | - helper.py
    `- settings.py

2 direktori, 6 file

Perintah:

$ python import_submodule.py

Keluaran:

settings
helper
Helper in lib.settings
someobject
Helper in lib.foo.someobject

# ./import_submodule.py
import fnmatch, os
from lib.settings import Values
from lib import Helper

print
for root, dirs, files in os.walk('.'):
    for f in fnmatch.filter(files, '*.py'):
        print "# %s/%s" % (os.path.basename(root), f)
        print open(os.path.join(root, f)).read()
        print


# lib/helper.py
print 'helper'
class Helper(object):
    def __init__(self, module_name):
        print "Helper in", module_name


# lib/settings.py
print "settings"
import helper

class Values(object):
    pass

helper.Helper(__name__)


# lib/__init__.py
#from __future__ import absolute_import
import settings, foo.someobject, helper

Helper = helper.Helper


# foo/someobject.py
print "someobject"
from .. import helper

helper.Helper(__name__)


# foo/__init__.py
import someobject

59
2018-02-24 18:52



Jika lib/__init__.py mendefinisikan kelas Pembantu kemudian di settings.py Anda dapat menggunakan:

from . import Helper

Ini berfungsi karena. adalah direktori saat ini, dan bertindak sebagai sinonim untuk paket lib dari sudut pandang modul pengaturan. Perhatikan bahwa tidak perlu mengekspor Helper melalui __all__.

(Dikonfirmasi dengan python 2.7.10, berjalan di Windows.)


8
2018-06-30 14:27



Anda tinggal memasukkannya ke __init__.py.

Jadi dengan test / classes.py menjadi:

class A(object): pass
class B(object): pass

... dan test / __ init__.py sedang:

from classes import *

class Helper(object): pass

Anda dapat mengimpor tes dan memiliki akses ke A, B, dan Helper

>>> import test
>>> test.A
<class 'test.classes.A'>
>>> test.B
<class 'test.classes.B'>
>>> test.Helper
<class 'test.Helper'>

7
2018-02-24 17:42



Sunting, karena saya salah memahami pertanyaan:

Taruh saja Helper kelas masuk __init__.py. Itu sempurna pythonic. Rasanya aneh datang dari bahasa seperti Java.


4
2018-02-24 17:42



Tambahkan sesuatu seperti ini lib/__init__.py

from .helperclass import Helper

sekarang Anda dapat mengimpornya secara langsung:

from lib import Helper


3
2018-06-03 09:39



Ya, itu mungkin. Anda mungkin juga ingin menentukan __all__ di __init__.py file. Ini adalah daftar modul yang akan diimpor ketika Anda melakukannya

from lib import *

1
2018-02-24 17:49



Mungkin ini bisa berfungsi:

import __init__ as lib

-5
2018-01-04 15:09