Apakah boleh menggunakan tanda hubung dalam file Python ketika mencoba mengimpornya?

149

Pada dasarnya ketika saya memiliki file python seperti:

python-code.py

dan gunakan:

import (python-code)

penerjemah memberi saya kesalahan sintaks.

Ada ide tentang cara memperbaikinya? Apakah tanda hubung ilegal pada nama file python?

Joan Venge
sumber

Jawaban:

167

Anda harus memeriksa PEP 8 , Panduan Gaya untuk Kode Python:

Nama Paket dan Modul Modul harus memiliki nama pendek, semua huruf kecil. Garis bawah dapat digunakan dalam nama modul jika itu meningkatkan keterbacaan. Paket-paket python juga harus memiliki nama-nama kecil, huruf kecil semua, meskipun penggunaan garis bawah tidak disarankan.

Karena nama modul dipetakan ke nama file, dan beberapa sistem file tidak sensitif huruf dan memotong nama panjang, penting bahwa nama modul dipilih agar cukup pendek - ini tidak akan menjadi masalah pada Unix, tetapi mungkin masalah ketika kode diangkut ke versi Mac atau Windows yang lebih lama, atau DOS.

Dengan kata lain: ganti nama file Anda :)

Paolo Bergantino
sumber
75
masalahnya tidak ada hubungannya dengan gaya, ini adalah kesalahan sintaksis
4
Seperti yang ditunjukkan di bawah ini, adalah mungkin untuk masih memiliki file dengan nama ini, sehingga panduan gaya sangat relevan.
Paolo Bergantino
5
Ini bisa sangat membantu untuk menggunakan tanda hubung dalam direktori Python dan nama file ketika Anda secara eksplisit ingin mencegah impor. Misalnya dalam (katakanlah) proyek Django, Anda mungkin memiliki skrip yang ditulis dengan Python yang tidak boleh dialamatkan sebagai aplikasi. Anda dapat meletakkan ini di folder sepertiops-scripts dan tahu mereka tidak dapat diimpor menggunakan pendekatan namespace paket normal. Atau satu skrip dapat diberi nama stop-website.pyuntuk efek yang sama. Semua ini masih dapat diimpor melalui runpydan beberapa metode lain tentu saja, tetapi ini membantu menghindari beberapa kesalahan umum.
Chris Johnson
Mengganti nama modul bisa menjadi masalah, terutama jika Anda mengandalkan standar lain. Dalam kasus saya, saya menggunakan file python cgi di cgi-binfolder (melakukan unitttests pada mereka), yang merupakan standar afaik. Kecuali Anda memiliki case yang jarang seperti ini, pasti ganti nama modul Anda jika Anda memiliki kontrol atasnya.
NuclearPeon
1
Saya baru saja menemukan bahwa PyDev akan mengizinkan nama direktori dengan tanda hubung, tetapi tidak akan menampilkan kelas dan / atau variabel internal dalam file .py yang terdapat dalam direktori itu.
user5920660
122

Satu hal lagi yang perlu diperhatikan dalam kode Anda adalah bahwa impor bukan fungsi. Jadi import(python-code)seharusnya import python-codeyang, seperti beberapa telah disebutkan, ditafsirkan sebagai "impor kode minus python", bukan apa yang Anda maksudkan. Jika Anda benar-benar perlu mengimpor file dengan tanda hubung dalam namanya, Anda dapat melakukan hal berikut ::

python_code = __import__('python-code')

Tetapi, seperti juga disebutkan di atas, ini tidak benar-benar direkomendasikan. Anda harus mengubah nama file jika itu sesuatu yang Anda kendalikan.

Rick Copeland
sumber
@KevinAudleman apakah Anda memiliki contoh kerja menggunakan lib impor dengan file yang ditulis dgn tanda penghubung? Saya mencoba dan gagal.
Tom Hale
@TomHale importlib.import_module ('abmodule-1') harus berfungsi. Jika import_module Anda tidak berfungsi, saya pikir impor normal juga tidak akan berfungsi.
Ian Lin
63

TLDR

Tanda hubung tidak ilegal tetapi Anda tidak boleh menggunakannya karena 3 alasan:

  1. Anda memerlukan sintaks khusus untuk mengimpor file dengan tanda hubung
  2. Tidak ada yang mengharapkan nama modul dengan tanda hubung
  3. Itu bertentangan dengan rekomendasi dari Panduan Gaya Python

Jika Anda benar-benar perlu mengimpor nama file dengan tanda hubung sintaks khususnya adalah ini:

module_name = __import__('module-name')

Ingin tahu mengapa kita membutuhkan sintaks khusus?

Alasan untuk sintaks khusus adalah bahwa ketika Anda menulis import somenameAnda membuat objek modul dengan pengidentifikasi somename(sehingga nanti Anda dapat menggunakannya dengan misalnya somename.funcname). Tentu saja module-namebukan pengidentifikasi yang valid dan karenanya sintaks khusus yang memberikan yang valid.

Anda tidak mengerti mengapa nama modul bukan pengidentifikasi yang valid?

Jangan khawatir - saya juga tidak. Berikut tip untuk membantu Anda: Lihat pada baris python ini: x=var1-var2. Apakah Anda melihat pengurangan di sisi kanan penugasan atau nama variabel dengan tanda hubung?

PS

Tidak ada yang orisinal dalam jawaban saya kecuali termasuk apa yang saya anggap sebagai bit informasi yang paling relevan dari semua jawaban lain di satu tempat

ndemou
sumber
Saya mencoba menggunakan impor ini paket pip dengan tanda hubung di dalamnya. psycopg2_binary = import_module('psycopg2-binary'). Kesalahan => ModuleNotFoundError: No module named 'psycopg2-binary'. Tetapi psycopg2-binarysudah terpasang. Tidak tahu cara memasukkannya.
Mote Zart
Mungkin itu masalah jalur. Lihatlah chrisyeh96.github.io/2017/08/08/…
ndemou
32

Masalahnya adalah itu python-codebukan pengidentifikasi. Pengurai melihat ini sebagai pythonminus code. Tentu saja ini tidak akan melakukan apa yang Anda minta. Anda perlu menggunakan nama file yang juga merupakan pengidentifikasi python yang valid. Coba ganti -dengan garis bawah.

SingleNegationElimination
sumber
4
+1. Jangan pernah berpikir bahwa nama file kode sumber Python harus menjadi pengidentifikasi yang valid, karena nama file akan digunakan untuk merujuk ke objek modul.
andy
5

Anda mungkin dapat mengimpornya melalui beberapa __import__peretasan, tetapi jika Anda belum tahu caranya, Anda seharusnya tidak. Nama modul Python haruslah nama variabel yang valid ("pengidentifikasi") - itu artinya jika Anda memiliki modul foo_bar, Anda dapat menggunakannya dari dalam Python ( print foo_bar). Anda tidak akan dapat melakukannya dengan nama yang aneh ( print foo-bar-> kesalahan sintaks).

John Millikin
sumber
5

Pada Python 3 gunakan import_module :

from importlib import import_module
python_code = import_module('python-code')

Lebih umum,

import_module('package.subpackage.module')
e18r
sumber
1

Meskipun penamaan file yang tepat adalah yang terbaik, jika python-codetidak di bawah kendali kami, peretasan menggunakan __import__lebih baik daripada menyalin, mengganti nama, atau main-main dengan kode penulis lain. Namun, saya mencoba dan tidak berhasil kecuali saya mengganti nama file dengan menambahkan .pyekstensi. Setelah melihat dokumen untuk mendapatkan cara mendapatkan deskripsi .py, saya berakhir dengan ini:

import imp

try:
    python_code_file = open("python-code")
    python_code = imp.load_module('python_code', python_code_file, './python-code', ('.py', 'U', 1))
finally:
    python_code_file.close()

Itu menciptakan file baru python-codecdi jalankan pertama.

Ale
sumber