Bitta python .py faylini o'zaro bog'liqlik bilan bir nechta fayllarga ajratish

Men yozgan katta python modulini katalogdagi bir nechta fayllarga bo'lishni xohlayman, bu erda har bir fayl modul ichidagi boshqa funktsiyalarga bog'liq bo'lishi mumkin yoki bo'lmasligi mumkin. Men o'ylab topgan oddiy misol:

Birinchidan, bu erda o'ziga xos .py moduli mavjud

#[/pie.py]
def getpi():
    return pi()

def pi():
    return 3.1416

Shubhasiz, bu ikkala funktsiyani import qilish va chaqirishda yaxshi ishlaydi. Endi men uni to'ldirish uchun init.py fayli bilan turli fayllarga ajratdim:

#[/pie/__init__.py]
from getpi import *
from pi import *
__all__=['getpi','pi']

#[/pie/getpi.py]
def getpi():
    return pi()

#[/pie/pi.py]
def pi():
    return 3.1416

Getpi() ning pi() ga bog'liqligi tufayli uni hozirgi tuzilgan deb atash istisnoga olib keladi:

>>> import pie
>>> pie.getpi()

Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    pie.getpi()
  File "C:\python\pie\getpi.py", line 2, in getpi
    return pi()
NameError: global name 'pi' is not defined

Va shuning uchun bu muammoni hal qilish uchun mening hozirgi yechimim init.py ni shunday yozishdir:

#[/pie/__init__.py]
import os as _os

__all__ = []
for _f in  _os.listdir(__path__[0]):
    if not _f == '__init__.py' and _f.endswith('.py'):
        execfile('%s\\%s'%(__path__[0],_f))
        __all__.append(_os.path.splitext(_f)[0])

Shunday qilib, endi u yaxshi ishlaydi:

>>> import pie
>>> pie.getpi()
3.1416

Shunday qilib, endi hamma narsa xuddi bitta .py faylida joylashgandek ishlaydi. init.py barcha individual funktsiyalar uchun zarur bo'lgan barcha yuqori darajadagi importlarni (numpy, os, sys, glob...) o'z ichiga olishi mumkin.

Modulni shu tarzda tuzish men uchun "to'g'ri" tuyuladi. Yangi funksiyalar keyingi importda avtomatik ravishda yuklanadi (har safar init.py qo‘shish shart emas). Bu menga katalog ichidagi narsalarni ko'rib chiqish orqali qaysi funksiyalardan foydalanish uchun mo'ljallanganligini bir qarashda ko'rish imkonini beradi, shuningdek, hamma narsani alifbo tartibida yaxshi tartiblangan holda saqlaydi.

Ayni paytda men ko'ra oladigan yagona salbiy tomoni shundaki, faqat init.py bayt-kompilyatsiya qilinadi va sub .py fayllari emas. Lekin yuklash tezligi muammo emas edi, shuning uchun men bunga qarshi emasman. Bundan tashqari, men bu qadoqlash bilan bog'liq muammoga olib kelishi mumkinligini tushunaman, lekin bu ham menga qarshi emas, chunki bizning skriptlarimiz o'z tahrirni nazorat qilish tizimimiz orqali tarqatiladi.

Bu python modulini tuzishning maqbul usulimi? Agar yo'q bo'lsa, men to'g'ri qilgan narsaga erishishning to'g'ri yo'li qanday bo'lar edi?


person Fnord    schedule 25.03.2014    source manba


Javoblar (1)


"To'g'ri" yo'l kerakli modullarni kerakli joyga import qilishdir:

# pi.py
def pi(): return 3.1417

# getpi.py
from .pi import pi
def getpi(): return pi()

# __init__.py
from .pi import *
from .getpi import *

Sizda tsiklik bog'liqliklar yo'qligiga ishonch hosil qiling. Bular har qanday holatda ham yomon a>, lekin kerakli darajaga qadar abstraktsiya qilish orqali ulardan qochishingiz mumkin.

person Niklas B.    schedule 25.03.2014