web-gelistirme-sc.com

Bir modülün yolu nasıl alınır?

Modülün değişip değişmediğini tespit etmek istiyorum. Şimdi, inotify kullanmak basittir, sadece bildirim almak istediğiniz dizini bilmeniz yeterlidir.

Bir modülün yolunu python'da nasıl edinebilirim?

633
Cheery
import a_module
print(a_module.__file__)

Aslında, en azından Mac OS X'te yüklenen .pyc dosyasının yolunu gösterecektir. Bu nedenle şunları yapabilirsiniz:

import os
path = os.path.dirname(a_module.__file__)

Ayrıca deneyebilirsiniz:

path = os.path.abspath(a_module.__file__)

Modülün dizinini almak için.

737
orestis

Python'da inspect modülü var.

Resmi belgeler

Inspect modülü, modüller, sınıflar, yöntemler, fonksiyonlar, geri izleme, kare nesneler ve kod nesneleri gibi canlı nesneler hakkında bilgi edinmeye yardımcı olmak için çeşitli yararlı işlevler sağlar. Örneğin, bir sınıfın içeriğini incelemenize, bir yöntemin kaynak kodunu almanıza, bir işlev için bağımsız değişken listesini çıkarmanıza ve biçimlendirmenize ya da ayrıntılı bir geri izleme görüntülemek için gereken tüm bilgileri almanıza yardımcı olabilir.

Örnek:

>>> import os
>>> import inspect
>>> inspect.getfile(os)
'/usr/lib64/python2.7/os.pyc'
>>> inspect.getfile(inspect)
'/usr/lib64/python2.7/inspect.pyc'
>>> os.path.dirname(inspect.getfile(inspect))
'/usr/lib64/python2.7'
222
SummerBreeze

Diğer cevapların söylediği gibi, bunu yapmanın en iyi yolu __file__ iledir (aşağıda tekrar gösterilmiştir). Ancak, önemli bir uyarı vardır, ki eğer modülü kendi başına çalıştırıyorsanız __file__ mevcut değildir (örneğin, __main__ olarak).

Örneğin, iki dosyanız olduğunu söyleyin (ikisi de PYTHONPATH'inizde):

#/path1/foo.py
import bar
print(bar.__file__)

ve

#/path2/bar.py
import os
print(os.getcwd())
print(__file__)

Çalışan foo.py çıktıyı verir:

/path1        # "import bar" causes the line "print(os.getcwd())" to run
/path2/bar.py # then "print(__file__)" runs
/path2/bar.py # then the import statement finishes and "print(bar.__file__)" runs

Bar.py 'ı kendi kendine çalıştırmayı denersen NASIL alırsın:

/path2                              # "print(os.getcwd())" still works fine
Traceback (most recent call last):  # but __file__ doesn't exist if bar.py is running as main
  File "/path2/bar.py", line 3, in <module>
    print(__file__)
NameError: name '__file__' is not defined 

Bu yardımcı olur umarım. Bu uyarı, sunulan diğer çözümleri test ederken bana zaman ve kafa karışıklığına neden oldu.

64
mcstrother

Bu soruda da birkaç varyasyonla mücadele etmeye çalışacağım:

  1. denilen betiğin yolunu bulma
  2. şu anda çalışan betiğin yolunu bulma
  3. çağrılan betiğin dizinini bulma

(Bu sorulardan bazılarına SO üzerinden soru soruldu, ancak bunlar kopya olarak kapatıldı ve buraya yönlendirildi.)

__file__ Kullanmanın Uyarıları

Aldığınız bir modül için:

import something
something.__file__ 

modülün mutlak yolunu döndürür. Ancak, aşağıdaki komut dosyası foo.py verildiğinde:

#foo.py
print '__file__', __file__

'Python foo.py' ile çağırmak basitçe 'foo.py' döndürür. Bir Shebang eklerseniz:

#!/usr/bin/python 
#foo.py
print '__file__', __file__

ve ./foo.py kullanarak arayın, './foo.py' döndürür. Farklı bir dizinden aramak (örneğin, dizin çubuğuna foo.py koymak), sonra ikisini de aramak

python bar/foo.py

veya bir Shebang eklemek ve dosyayı doğrudan çalıştırmak:

bar/foo.py

'bar/foo.py' ( göreceli yol) döndürür.

Dizini bulmak

Şimdi oraya gidilecek dizine ulaşmak için os.path.dirname(__file__) ayrıca zor olabilir. En azından sistemimde, dosya ile aynı dizinden çağırırsanız, boş bir dize döndürür. ex.

# foo.py
import os
print '__file__ is:', __file__
print 'os.path.dirname(__file__) is:', os.path.dirname(__file__)

çıkacak:

__file__ is: foo.py
os.path.dirname(__file__) is: 

Başka bir deyişle, boş bir dize döndürür, bu nedenle geçerli dosyası için kullanmak istiyorsanız ( yerine ithal edilen bir modülün dosyası . Bunu aşmak için abspath çağrısına sarabilirsiniz:

# foo.py
import os
print 'os.path.abspath(__file__) is:', os.path.abspath(__file__)
print 'os.path.dirname(os.path.abspath(__file__)) is:', os.path.dirname(os.path.abspath(__file__))

hangi gibi bir şey çıktı:

os.path.abspath(__file__) is: /home/user/bar/foo.py
os.path.dirname(os.path.abspath(__file__)) is: /home/user/bar

Abspath () 'in sembolik bağlantıları çözmediğini unutmayın. Bunu yapmak istiyorsanız, bunun yerine realpath () kullanın. Örneğin, aşağıdaki içeriğe sahip bir file link file_import_testing_link'i file_import_testing.py'ye işaret ederek yapmak:

import os
print 'abspath(__file__)',os.path.abspath(__file__)
print 'realpath(__file__)',os.path.realpath(__file__)

çalıştırma, mutlak yolları aşağıdaki gibi basar:

abspath(__file__) /home/user/file_test_link
realpath(__file__) /home/user/file_test.py

file_import_testing_link -> file_import_testing.py

Teftiş kullanarak

@ SummerBreeze inceleyin modülünü kullanarak bahseder.

Bu iyi çalışıyor gibi görünüyor ve ithal modüller için oldukça özlü:

import os
import inspect
print 'inspect.getfile(os) is:', inspect.getfile(os)

itaatkar mutlak yolu döndürür. Ancak şu anda çalışan komut dosyasının yolunu bulmak için, onu kullanmanın bir yolunu görmedim.

34
jpgeek

Neden kimsenin bu konuda konuştuğunu anlamıyorum, ama bana göre en basit çözüm imp.find_module ("modulename") (dokümantasyon - burada ):

import imp
imp.find_module("os")

Yol ikinci konumda iken bir Tuple verir:

(<open file '/usr/lib/python2.7/os.py', mode 'U' at 0x7f44528d7540>,
'/usr/lib/python2.7/os.py',
('.py', 'U', 1))

Bu yöntemin "denetle" seçeneğine göre avantajı, çalışması için modülü içe aktarmanıza gerek kalmaması ve girdi içinde bir dize kullanmanızdır. Örneğin başka bir komut dosyasında çağrılan modülleri kontrol ederken kullanışlıdır.

DÜZENLE:

Python3'te importlib modülü şunları yapmalıdır:

importlib.util.find_spec Doktoru:

Belirtilen modül için belirtimi döndür.

İlk olarak, modülün zaten içe aktarılıp aktarılmadığını görmek için sys.modules denetlenir. Öyleyse, sys.modules [name]. spec döndürülür. Bu Yok olarak ayarlanırsa, ValueError yükseltilir. Modül sys.modules'da değilse, sys.meta_path, buluculara verilen 'path' değerine sahip uygun bir özellik için aranır. Herhangi bir özellik bulunamazsa hiçbiri döndürülmez.

Ad alt modül için ise (bir nokta içeriyorsa), ana modül otomatik olarak içe aktarılır.

Name ve package argümanları importlib.import_module () ile aynı şekilde çalışır. Başka bir deyişle, göreceli modül adları (baş noktalara sahip) çalışır.

26
PlasmaBinturong

Bu önemsizdi.

Her modülün göreceli yolunu şu anda bulunduğunuz yerden gösteren bir __file__ değişkeni vardır.

Bu nedenle, modülün bunu bildirmesi için bir dizin almak:

os.path.dirname(__file__)
18
Cheery
import os
path = os.path.abspath(__file__)
dir_path = os.path.dirname(path)
17
vinoth

Komut Satırı Yardımcı Programı

Bir komut satırı yardımcı programına Tweak yapabilirsiniz

python-which <package name>

enter image description here


/usr/local/bin/python-which oluştur

#!/usr/bin/env python

import importlib
import os
import sys

args = sys.argv[1:]
if len(args) > 0:
    module = importlib.import_module(args[0])
    print os.path.dirname(module.__file__)

Çalıştırılabilir yap

Sudo chmod +x /usr/local/bin/python-which
9
Jossef Harush
import module
print module.__path__

Paketler __path__ adlı özel bir özelliği daha destekler. Bu, dosyadaki kod çalıştırılmadan önce paketin __init__.py kodunu içeren dizinin adını içeren bir liste olarak başlatılır. Bu değişken değiştirilebilir; bunu yapmak, gelecekteki araştırmaları paketin içinde yer alan alt paketler ve alt paketler için etkiler.

Bu özellik çoğu zaman gerekli olmamakla birlikte, bir pakette bulunan modül kümesini genişletmek için kullanılabilir.

Kaynak

7
Lukas Greblikas

Bu yüzden py2exe ile bunu yapmaya çalışırken oldukça fazla zaman harcadım Sorun betiğin temel klasörünü bir python betiği olarak mı yoksa bir py2exe yürütülebilir dosyası olarak mı çalıştırmaktı. Ayrıca, geçerli klasörden, başka bir klasörden veya sistemin yolundan (en zoru) çalıştırılıp çalıştırılmadığını çalışmasını sağlamak için.

Sonunda bu yaklaşımı kullandım, py2exe'de çalıştırmanın bir göstergesi olarak sys.frozen kullanarak:

import os,sys
if hasattr(sys,'frozen'): # only when running in py2exe this exists
    base = sys.prefix
else: # otherwise this is a regular python script
    base = os.path.dirname(os.path.realpath(__file__))
7
uri

sadece modülünüzü içe aktarabilir ve sonra ismine basabilirsiniz ve tam yolunu elde edersiniz.

>>> import os
>>> os
<module 'os' from 'C:\\Users\\Hassan Ashraf\\AppData\\Local\\Programs\\Python\\Python36-32\\lib\\os.py'>
>>>
4
Hassan Ashraf

__file__ kullanmanın tek ihmali geçerli olduğunda, göreceli dizin boştur (yani, betiğin bulunduğu dizinden bir komut dosyası olarak çalışırken), o zaman önemsiz bir çözüm:

import os.path
mydir = os.path.dirname(__file__) or '.'
full  = os.path.abspath(mydir)
print __file__, mydir, full

Ve sonuç:

$ python teste.py 
teste.py . /home/user/work/teste

İşin püf noktası dirname() çağrısından sonra or '.' içinde. Dir, . olarak ayarlar, yani geçerli dizin ve yolla ilgili herhangi bir işlev için geçerli bir dizindir.

Bu nedenle, abspath() işlevini kullanmak gerçekten gerekli değildir. Ama yine de kullanırsanız, hile gerekli değildir: abspath() boş yolları kabul eder ve onu geçerli dizin olarak yorumlar.

3
MestreLion

Ortak bir senaryoya (Python 3'te) katkıda bulunmak ve bu konudaki birkaç yaklaşımı keşfetmek istiyorum.

Yerleşik işlev open () , göreli veya mutlak yolu ilk argümanı olarak kabul eder. Göreceli yol geçerli çalışma dizinine göre olarak değerlendirilir, ancak dosyaya mutlak yolun iletilmesi önerilir.

Basitçe söylemek gerekirse, aşağıdaki kodla bir komut dosyası çalıştırırsanız, değil example.txt dosyasının komut dosyasının bulunduğu dizinde oluşturulacağının garantisidir. dosya bulunur:

with open('example.txt', 'w'):
    pass

Bu kodu düzeltmek için komut dosyasının yolunu bulmalı ve mutlak hale getirmeliyiz. Yolun mutlak olmasını sağlamak için sadece os.path.realpath () işlevini kullanırız. Komut dosyasının yolunu bulmak için çeşitli yol sonuçlarını döndüren birkaç ortak işlev vardır:

  • os.getcwd()
  • os.path.realpath('example.txt')
  • sys.argv[0]
  • __file__

Her iki işlev de os.getcwd () ve os.path.realpath ()geçerli çalışma dizini 'ye dayalı yol sonuçları döndürür. Genelde istediğimiz şey değil. Listeyi kök betiğin kendisinde veya içinde çağırıp çağırmamanıza bakılmaksızın, sys.argv listesinin ilk öğesi kök komut dosyasının yol (çalıştırdığınız komut dosyası) 'dır. modüllerinden herhangi biri. Bazı durumlarda kullanışlı olabilir. _ FILE _ değişkeni, çağrıldığı modülün yolunu içerir.


Aşağıdaki kod, komut dosyasının bulunduğu dizinde example.txt dosyasını doğru bir şekilde oluşturur:

filedir = os.path.dirname(os.path.realpath(__file__))
filepath = os.path.join(filedir, 'example.txt')

with open(filepath, 'w'):
    pass
3
Jeyekomon

Bir python paketinin modüllerinden, paketle aynı dizinde bulunan bir dosyaya başvurmak zorunda kaldım. Ör.

some_dir/
  maincli.py
  top_package/
    __init__.py
    level_one_a/
      __init__.py
      my_lib_a.py
      level_two/
        __init__.py
        hello_world.py
    level_one_b/
      __init__.py
      my_lib_b.py

Bu yüzden yukarıda top_package ve maincli.py'nin aynı dizinde olduğunu bilerek, my_lib_a.py modülünden maincli.py'yi çağırmak zorunda kaldım. Maincli.py dosyasının yolunu aşağıda bulabilirsiniz:

import sys
import os
import imp


class ConfigurationException(Exception):
    pass


# inside of my_lib_a.py
def get_maincli_path():
    maincli_path = os.path.abspath(imp.find_module('maincli')[1])
    # top_package = __package__.split('.')[0]
    # mod = sys.modules.get(top_package)
    # modfile = mod.__file__
    # pkg_in_dir = os.path.dirname(os.path.dirname(os.path.abspath(modfile)))
    # maincli_path = os.path.join(pkg_in_dir, 'maincli.py')

    if not os.path.exists(maincli_path):
        err_msg = 'This script expects that "maincli.py" be installed to the '\
        'same directory: "{0}"'.format(maincli_path)
        raise ConfigurationException(err_msg)

    return maincli_path

PlasmaBinturong tarafından gönderilen ilanı temel alarak kodu değiştirdim.

1
Al Conrad

Bunu dinamik olarak bir "programda" yapmak istiyorsanız bu kodu deneyin:
Amacım, modülün tam adını "hardcode" olarak bilmiyor olabilirsiniz. Bir listeden seçilebilir veya şu anda __file__ kullanmak için çalışmıyor olabilir.

(Biliyorum, Python 3'te çalışmayacak)

global modpath
modname = 'os' #This can be any module name on the fly
#Create a file called "modname.py"
f=open("modname.py","w")
f.write("import "+modname+"\n")
f.write("modpath = "+modname+"\n")
f.close()
#Call the file with execfile()
execfile('modname.py')
print modpath
<module 'os' from 'C:\Python27\lib\os.pyc'>

"Global" sorundan kurtulmaya çalıştım, ancak çalışmadığı durumlarda Python 3'te "execfile ()" taklit edilebilir diye düşünüyorum. yeniden kullanın.

1
Robin Randall

Komut dosyanızdan mutlak yolu bilmek istiyorsanız Path object:

from pathlib import Path

print(Path().absolute())
print(Path().resolve('.'))
print(Path().cwd())

cwd () yöntemi

Geçerli dizini temsil eden yeni bir yol nesnesi döndür (os.getcwd () tarafından döndürüldüğü gibi)

solve () yöntemi

Herhangi bir sembolik bağlantıyı çözerek yolu mutlak yapın. Yeni bir yol nesnesi döndürülür:

1
Vlad Bezden

Paketin kök yolunu modüllerinden herhangi birinden almak isterseniz, aşağıdakiler çalışır (Python 3.6'da test edilmiştir):

from . import __path__ as ROOT_PATH
print(ROOT_PATH)

Ana __init__.py yolu ayrıca bunun yerine __file__ kullanılarak da başvuruda bulunabilir.

Bu yardımcı olur umarım!

0
fr_andres