เกี่ยวกับการ import ครับ

ผมสร้างโปรแกรมบนระบบอูบุนตูที่มีโครงสร้างการเก็บโมดูลเป็นลักษณะนี้

PackageFolder/
__init__.py
runapp.py

Level_1_SubFolder/
__init__.py
mod1.py
mod2.py

Level_1_SubFolder/
__init__.py
mod3.py
mod4.py

ตอนที่ผมรันจาก runapp.py ที่อยู่ภายใน packagefolder ก็สามารถ import ใช้านได้ แต่หลังจากที่สร้าง debian package แล้วจะต้องแยกไฟล์ runapp.py ไปไว้ที่ /usr/bin ส่วนโมดูลอื่นๆ ก็ไปไว้ที่ /usr/share/myapp ปัญหาของผมจะแยกไว้เป็นข้อๆ นะครับ

  • หลังจากรันไฟล์ runapp.py แล้วมันไม่พบโมดูลที่ผม import เข้ามา ผมลอง sys.path.insert(0,"/usr/share/myapp") แล้วก็ยัง import ไม่ได้ครับ ผมต้องแก้ในไฟล์ runapp.py ให้สามารถ import ได้อย่างไรครับ
  • ในไฟล์ __init__.py ผมเขียนกำหนด path ให้กับตัวแปร __path__ กับกำหนดโมดูลให้ตัวแปร __all__ ต้องมีอะไรเพิ่มเติมอีกบ้างครับหรือว่าผมเขียนผิด
  • ผมลองสังเกตุดูว่าที่ /usr/share/myapp ไฟล์ __init__.py ที่อยู่กับไฟล์ runapp.py ไม่ได้ถูกคอมไพล์เป็น .pyc มันจะมีผลที่โปรแกรมผมหาโมดูลไม่เจอรึเปล่าครับ
  • รบกวนช่วยตอบด้วยนะครับ คำถามอาจจะดูงงๆ อยู่บ้าง ผมก็ไม่รู้จะอธิบายอย่างไรดีน่ะครับ ติดตรงนี้มาซักพักแล้วครับ

    ทำได้แล้วครับ ที่ผมแก้คือ fixed path ไปที่โฟลเดอร์แต่ละอันที่มีเลย แล้ว insert ไปไว้ใน sys.path ทีละตัวๆ

    แต่ก็ยังไม่ถูกใจผมอยู่ดี

    ถ้าผมต้องการที่จะ import แบบ

    from SubFolder.Module import *

    นี่ต้องทำอย่างไรบ้างครับ

    sugree's picture

    runapp.py ควรอยู่นอก module แล้วก็เซ็ต PYTHONPATH="."

    ทำถูกหมดแล้ว อย่างที่คุณ sugree ว่าครับ ขาดแต่ set PYTHONPATH ไม่งั้น ก็ทำ link ออกมาจาก site-package ของตัว python ไปเลย ถ้าไม่อยาก set PYTHONPATH อีก ;)

    ขอบคุณมากครับสำหรับคำตอบ แล้วเคยมีใครเคยสร้าง debian package บ้างมั้ยครับ (หรือว่าผมควรตั้งกระทู้ใหม่ดี?)

    sugree's picture

    ผมสร้างประจำ ง่ายมากๆ อ่านหลักการที่ http://debianclub.org/node/60

    ขอคำแนะนำหน่อยครับ คือว่าผมสร้างแพคเก็จเสร็จเรียบร้อยแล้ว โดยผมติดตั้งไฟล์สำหรับรันไว้ที่ /usr/bin ส่วนไฟล์ข้อมูลผมจะเอาไว้ที่ /usr/share/myapp


    ในไฟล์ rules ตรงส่วน install: build ของผมเป็นแบบนี้ครับ
    dh_testdir
    dh_testroot
    dh_clean -k
    dh_installdirs

    mkdir -p $(CURDIR)/debian/myapp

    # Insert commands
    cp runapp.py $(CURDIR)/debian/myapp/usr/bin/runapp.py

    # Install data files
    mkdir -p $(CURDIR)/debian/myapp/usr/share/myapp
    cp -r data/ $(CURDIR)/debian/myapp/usr/share/myapp/data


    ที่บรรทัดสุดท้ายข้อมูลจะถูกติดตั้งไปที่ /usr/share/myapp/data

    แต่โปรแกรมผมต้องเซฟข้อมูลกลับเข้าไปด้วยซึ่งมันติด permission เลยทำงานต่อไม่ได้

  • ถ้าผมต้องการให้ข้อมูลผมไปอยู่ใน /home/username/.myapp จะสามารถทำได้ไหมครับ (ชื่อเครื่องแต่ละเครื่องมันไม่เหมือนกันจะกำหนดตายตัวก็ไม่ได้) ถ้าได้ต้องตั้งกฎที่ไฟล์ rules อย่างไรบ้างครับ
  • มีวิธีตั้ง permission ให้โฟลเดอร์ที่อยู่ใน /usr/share นั้นสามารถเซฟข้อมูลได้ไหมครับ

  • รบกวนด้วยนะครับถ้าโปรแกรมผมทำเป็นแพ็คเกจแต่โปรแกรมใช้ไม่ได้นี่คงอารมณ์ค้างมากๆ เลยครับ

    ขอบคุณมากครับ

    sugree's picture

    ที่ว่ามาไม่เกี่ยวกับ rules ครับ มันขึ้นกับโปรแกรมของเรา ซึ่งในกรณีนี้จะต้องเพิ่มลอจิกนิดหน่อย

    1. ถ้าไม่เจอ $HOME/.myapp ก็สร้างซะ
    2. ถ้าไม่เจอ data ใน $HOME/.myapp ก็อ่านจาก dirname ของ runapp.py ../share/myapp
    3. เวลาเขียนให้เขียนใน $HOME/.myapp

    เข้าใจแล้วครับขอบคุณมากนะครับ ^^
    แล้วถ้าผมต้องการกำหนด path = $home/.myapp นี่จะเขียนใน python อย่างไรบ้างครับ

    เซ่ออีกแล้วผม มันก็มี os.environ() อยู่นี่นา ^^
    เปลี่ยนคำถามดีกว่าครับ แล้วผมจะตรวจสอบได้อย่างไรครับว่ามีโฟลเดอร์นี้อยู่และในโฟลเดอร์นี้มีข้อมูลอยู่

    edit: ผมลองไปอ่าน API ดูแล้วครับ มันจะมี os.path.exists(path), os.path.isdir(path) ไว้สำหรับหาว่ามี path นี้อยู่หรือไม่ ส่วนจะดูว่ามีข้อมูลอยู่หรือไม่ผมใช้ os.path.getsize(path)

    แล้วถ้าผมต้องการก๊อปปี้ข้อมูลไปที่ path ที่ผมกำหนดจะทำใน python ได้อย่างไรบ้างครับ?

    sugree's picture

    shlib ช่วยได้

    ขอบคุณมากครับ (แล้วมันใช่ตัวเดียวกันกับ shutil รึเปล่าครับ?)

    sugree's picture

    อ๊าก พิมพ์ผิด มือไว

    ย้าย Codenone

    ประกาศย้าย Codenone ไปใช้ Forum ของ Blognone แทนครับ ตามไปตั้งกระทู้ต่อได้ที่ Codenone Forum (รายละเอียดอ่านจากกระทู้ ย้าย Codenone ไปรวมกับ Blognone)

    กระทู้เก่าๆ จะย้ายตามไปในภายหลัง ตอนนี้ปิดการโพสต์กระทู้ไว้ เหลือไว้เฉพาะอ้างอิงเท่านั้น