Diğer Python dosyaları nasıl alınır?


798

Python'daki diğer dosyaları nasıl alabilirim?

  1. Nasıl belirli bir python dosyasını tam olarak alabilirim import file.py?
  2. Belirli bir dosya yerine klasörü nasıl alabilirim?
  3. Kullanıcı girişine göre çalışma zamanında dinamik olarak bir Python dosyası yüklemek istiyorum.
  4. Dosyadan sadece belirli bir parçayı nasıl yükleyeceğimi bilmek istiyorum.

Örneğin, main.pybende var:

from extra import * 

Bu bana tüm tanımları verse de extra.py, belki istediğim tek bir tanım:

def gap():
    print
    print

Ben ne eklerim importsadece almak deyimi gapgelen extra.py?


Yanıtlar:


443

importlibbir modülü programlı olarak içe aktarmak için Python 3'e eklendi. Bu sadece bir sarıcı dönünce __import__bakın belgeler .

import importlib

moduleName = input('Enter module name:')
importlib.import_module(moduleName)

Not: .pyuzantı kaldırılmalıdır moduleName. İşlev ayrıca packagegöreli içe aktarma için bir argüman tanımlar .


Güncelleme: Aşağıdaki cevap eski . Yukarıdaki en yeni alternatifi kullanın.

  1. Sadece import file'.py' uzantısı olmadan.

  2. Adlı boş bir dosya ekleyerek bir klasörü paket olarak işaretleyebilirsiniz __init__.py.

  3. __import__İşlevi kullanabilirsiniz . Modül adını dize olarak alır. (Tekrar: '.py' uzantısı olmayan modül adı.)

    pmName = input('Enter module name:')
    pm = __import__(pmName)
    print(dir(pm))

    Tip help(__import__)daha fazla ayrıntı için.


7
Bir eklerseniz import filenameiçin init .py sonra klasör adı olarak doğrudan modülünü alabilirsiniz.
CornSmith

9
itibaren help(__import__):Because this function is meant for use by the Python interpreter and not for general use it is better to use importlib.import_module() to programmatically import a module.
Tadhg McDonald-Jensen

6
Ya bir paket değil, sadece bir komut dosyasıysa?
Jonathan

3
Bir komut dosyasını aynı yolda içe aktarmak için (belki de bir Python arama yolunda bir komut dosyası için de çalışır), import filenamenoextPython 3.4.8 ile benim için iyi çalışıyor.
Alex Hall

7
2019'da hala doğru mu? Python3 veya 2 mi?
Sandburg

1031

Tüm artılarını ve eksilerini olan bir python dosyasını içe aktarmanın birçok yolu vardır.

Sadece sizin için çalışan ilk içe aktarma stratejisini aceleyle seçmeyin, aksi takdirde daha sonra ihtiyaçlarınızı karşılamadığını fark ettiğinizde kod tabanını yeniden yazmanız gerekir.

En kolay örnek 1'i açıklamaya başlayacağım, sonra en profesyonel ve sağlam örnek # 7'ye geçeceğim

Örnek 1, Python yorumlayıcılı bir python modülünü içe aktarın:

  1. Bunu /home/el/foo/fox.py içine koyun:

    def what_does_the_fox_say():
      print("vixens cry")
  2. Python yorumlayıcısına girin:

    el@apollo:/home/el/foo$ python
    Python 2.7.3 (default, Sep 26 2013, 20:03:06) 
    >>> import fox
    >>> fox.what_does_the_fox_say()
    vixens cry
    >>> 

    what_does_the_fox_say()Fox'u python yorumlayıcısı aracılığıyla içe aktardınız, fox.py içinden python işlevini çağırdınız.

Örnek 2, Diğer python dosyasını yerinde yürütmek için bir komut dosyasında execfileveya ( execPython 3'te ) kullanın :

  1. Bunu /home/el/foo2/mylib.py içine koyun:

    def moobar():
      print("hi")
  2. Bunu /home/el/foo2/main.py içine koyun:

    execfile("/home/el/foo2/mylib.py")
    moobar()
  3. dosyayı çalıştırın:

    el@apollo:/home/el/foo$ python main.py
    hi

    Moobar işlevi mylib.py dosyasından içe aktarıldı ve main.py dosyasında kullanıma sunuldu

Örnek 3, Kullanım ... içe aktar ... işlevselliği:

  1. Bunu /home/el/foo3/chekov.py içine koyun:

    def question():
      print "where are the nuclear wessels?"
  2. Bunu /home/el/foo3/main.py içine koyun:

    from chekov import question
    question()
  3. Bu şekilde çalıştırın:

    el@apollo:/home/el/foo3$ python main.py 
    where are the nuclear wessels?

    Chekov.py içinde başka işlevler tanımladıysanız, import *

Örnek 4, Alındığı yerden farklı bir dosya konumunda ise riaa.py dosyasını içe aktarın

  1. Bunu /home/el/foo4/stuff/riaa.py içine koyun:

    def watchout():
      print "computers are transforming into a noose and a yoke for humans"
  2. Bunu /home/el/foo4/main.py içine koyun:

    import sys 
    import os
    sys.path.append(os.path.abspath("/home/el/foo4/stuff"))
    from riaa import *
    watchout()
  3. Çalıştır:

    el@apollo:/home/el/foo4$ python main.py 
    computers are transforming into a noose and a yoke for humans

    Bu, yabancı dosyadaki her şeyi farklı bir dizinden içe aktarır.

Örnek 5, kullanım os.system("python yourfile.py")

import os
os.system("python yourfile.py")

Örnek 6, python startuphook'u piggyback yaparak dosyanızı içe aktarın:

Güncelleme: Bu örnek hem python2 hem de 3 için kullanılır, ancak şimdi yalnızca python2 için çalışır. python3, kullanıcı tanımlı tüm programlardan önce kodlarını küresel ad alanına kusursuz bir şekilde enjekte etmek için kullanarak, düşük yetenekli python kütüphanesi yazarları tarafından kötüye kullanıldığı için bu kullanıcı başlangıç ​​kanca özellik kümesinden kurtuldu. Bunun python3 için çalışmasını istiyorsanız, daha yaratıcı olmanız gerekir. Size nasıl yapılacağını söylersem, python geliştiricileri bu özellik kümesini de devre dışı bırakacak, böylece kendi başınızasınız.

Bkz. Https://docs.python.org/2/library/user.html

Bu kodu giriş dizininize ekleyin ~/.pythonrc.py

class secretclass:
    def secretmessage(cls, myarg):
        return myarg + " is if.. up in the sky, the sky"
    secretmessage = classmethod( secretmessage )

    def skycake(cls):
        return "cookie and sky pie people can't go up and "
    skycake = classmethod( skycake )

Bu kodu main.py dosyanıza koyun (herhangi bir yerde olabilir):

import user
msg = "The only way skycake tates good" 
msg = user.secretclass.secretmessage(msg)
msg += user.secretclass.skycake()
print(msg + " have the sky pie! SKYCAKE!")

Çalıştırın, şunu elde etmelisiniz:

$ python main.py
The only way skycake tates good is if.. up in the sky, 
the skycookie and sky pie people can't go up and  have the sky pie! 
SKYCAKE!

Burada bir hata alırsanız: ModuleNotFoundError: No module named 'user'python3 kullandığınız anlamına gelir, başlangıç ​​kancaları varsayılan olarak orada devre dışıdır.

Bu jist için kredi şu şekildedir: https://github.com/docwhat/homedir-examples/blob/master/python-commandline/.pythonrc.py Üst teknelerinizi gönderin.

Örnek 7, En Sağlam: Dosyaları çıplak içe aktarma komutuyla python'a içe aktarın:

  1. Yeni bir dizin oluşturun /home/el/foo5/
  2. Yeni bir dizin oluşturun /home/el/foo5/herp
  3. __init__.pyHerp altında boş bir dosya oluşturun :

    el@apollo:/home/el/foo5/herp$ touch __init__.py
    el@apollo:/home/el/foo5/herp$ ls
    __init__.py
  4. Yeni bir dizin oluşturun / home / el / foo5 / herp / derp

  5. Derp altında başka bir __init__.pydosya yapın:

    el@apollo:/home/el/foo5/herp/derp$ touch __init__.py
    el@apollo:/home/el/foo5/herp/derp$ ls
    __init__.py
  6. / Home / el / foo5 / herp / derp altında, yolo.pyBunu buraya koy adlı yeni bir dosya oluşturun :

    def skycake():
      print "SkyCake evolves to stay just beyond the cognitive reach of " +
      "the bulk of men. SKYCAKE!!"
  7. Gerçek anı, Yeni dosyayı yap /home/el/foo5/main.py, bunu oraya koy;

    from herp.derp.yolo import skycake
    skycake()
  8. Çalıştır:

    el@apollo:/home/el/foo5$ python main.py
    SkyCake evolves to stay just beyond the cognitive reach of the bulk 
    of men. SKYCAKE!!

    Boş __init__.pydosya, geliştiricinin bu dizini içe aktarılabilir bir paket olmasını amaçladığı python yorumlayıcısına bildirir.

TÜM .py dosyalarının bir dizinin altına nasıl ekleneceği ile ilgili yazımı görmek istiyorsanız, buraya bakın: https://stackoverflow.com/a/20753073/445131


6
Ayrıca Örnek 6: kullanarak eklemelisiniz __import__(py_file_name). İnanılmaz rehber yine
oriadam

4
Her ithalat sorunumda bu soruya ulaşıyorum ve her zaman sorunumu çözebiliyorum. Bana her yardım ettiğin zaman bunu oylayabilirsem, yapardım.
dgBP

4
Tüm bunlar arasındaki büyük fark nedir ve neden biri diğerinden daha iyidir? Örneğin 5, "çıplak alma komutuyla dosyaları python'a içe aktar" yazarsınız, ancak örnek 1, 3 ve 4'te de (çıplak?) Alma komutunu kullanırsınız, değil mi?
HelloGoodbye

34
İyi yanıt ama her zaman örnek olarak farklı bir içe aktarma dosyası kullanmanız okumayı zorlaştırıyor.
Mart'ta

2
Windows üzerinde çalışsanız bile içe aktarmanın büyük / küçük harfe duyarlı olduğunu vurgulamak isterim. Yani Module.py'ye sahip olamazsınız ve kod alma modülünüzde
olamaz

66

'Çalışma zamanında' bilinen belirli bir Python dosyasını içe aktarmak için:

import os
import sys

...

scriptpath = "../Test/"

# Add the directory containing your module to the Python path (wants absolute paths)
sys.path.append(os.path.abspath(scriptpath))

# Do the import
import MyModule

Arkadaşım bugün bunu hiç şans ile kontrol etti - dosya adı orada olmamalı gibi görünüyor. Üst dizinde yerel dosyayı kullandı ve sonunda "./" üst dizini (..) gibi çalıştı. Postadaki düzeltme sorunu reddedildi - muhtemelen yanlış anlama (?) Sys.path yazdırın ve emin değilseniz kayıtları karşılaştırın ...
Tom

29

Bir python dosyasını bir klasörden diğerine aktarmak için çok karmaşık yöntemleriniz yok. Bu klasörün bir python paketi olduğunu bildirmek için bir __init__.py dosyası oluşturun ve ardından içe aktarmak istediğiniz ana makine dosyanıza yazın.

from root.parent.folder.file import variable, class, whatever


15
Göreceli bir yol istersem ne olur?
17'de domih

21

Dokümanı içe aktar .. - Referans bağlantısı

__init__.pyDosyalar paket içeren Python bir muamele dizinleri yapmak için gerekli olan, bu istemeden modül arama yolunda geçerli modülleri gizleme gelen böyle dize olarak ortak bir adla dizinleri önlemek için yapılır.

__init__.pyyalnızca boş bir dosya olabilir, ancak paket için başlatma kodunu yürütebilir veya __all__değişkeni ayarlayabilir .

mydir/spam/__init__.py
mydir/spam/module.py
import spam.module
or
from spam import module

19

İlk durumda: Dosyayı A.pydosyaya aktarmak istiyorsunuz B.py, bu iki dosya aynı klasörde, şu şekilde:

. 
├── A.py 
└── B.py

Bunu dosyada yapabilirsiniz B.py:

import A

veya

from A import *

veya

from A import THINGS_YOU_WANT_TO_IMPORT_IN_A

Sonra dosyanın tüm işlevlerini kullanmak mümkün olacak A.pydosyadaB.py


İkinci durumda: Dosyayı folder/A.pydosyaya aktarmak istiyorsunuz B.py, bu iki dosya şu şekilde aynı klasörde değil:

.
├── B.py
└── folder
     └── A.py

Bunu B dosyasında yapabilirsiniz:

import folder.A

veya

from folder.A import *

veya

from folder.A import THINGS_YOU_WANT_TO_IMPORT_IN_A

Sonra dosyanın tüm işlevlerini kullanmak mümkün olacak A.pydosyadaB.py


Özet: İlk durumda, dosyaya A.pyiçe aktardığınız bir modül B.py, sözdizimini kullandınız import module_name. İkinci durumda, foldermodülü içeren paket A.pysözdizimini kullandınız import package_name.module_name.

Paketler ve modüller hakkında daha fazla bilgi için bu bağlantıya bakın .


Küçük bir değişiklikle denedim ve işe yaradı. from folder_a.script import *Script.py a klasörü altındadır.
Justin

+1 Aradığım şey bu. Diğer cevapları anlayamadım ama siz dizinleri kullanarak açıkladınız.
Black Thunder

Üst dizindeki bir py dosyasını almak istersem ne olur?
bytedev

1
@bytedev import sysve sys.path.append("..")dosyanın başına ekleyin . Buna göre: stackoverflow.com/a/48341902/6057480 . Test edilmiş, mükemmel çalışıyor, bunu yaptıktan sonra, üst dizine bir py dosyasını içe aktarabilir ve yine aynı dizine ve alt dizinlere py dosyalarını aktarabilirsiniz.
9'da Bohao LI

17
from file import function_name  ######## Importing specific function
function_name()                 ######## Calling function

ve

import file              ######## Importing whole package
file.function1_name()    ######## Calling function
file.function2_name()    ######## Calling function

İşte şu ana kadar anladığım iki basit yol ve kütüphane olarak almak istediğiniz "file.py" dosyanızın yalnızca geçerli dizininizde bulunduğundan emin olun.


9

Tanımlanan işlev bir dosyadaysa x.py:

def greet():
    print('Hello! How are you?')

İşlevi içe aktardığınız dosyaya şunu yazın:

from x import greet

Bu, bir dosyadaki tüm işlevleri almak istemiyorsanız kullanışlıdır.


7

.py dosyalarını içe aktarmanın en iyi yolu bu yöntemdir __init__.py. yapılacak en basit şey __init__.py, .py dosyanızın bulunduğu dizinde boş bir dosya oluşturmaktır .

Mike Grouchy bu yazı__init__.py python paketleri yapmak, almak ve kurmak için büyük bir açıklama ve kullanımı.


1
@GhostCat Yanıtımı güncelledim. "tercih edilir" bağlantısı için teşekkürler.
yüce

Ve herkesin sizin zaman diliminizde yaşamadığını anlayın.
GhostCat

4
Mike Grouchy'un gönderisinin içeriğini, özellikle de 404'lerin bağlantısından beri yayınlamış olmalısınız. web.archive.org/web/20190309045451/https://mikegrouchy.com/blog/…
qwr

6

Nasıl içe aktarırım dosyayı içe aktarmak ve adının kısaltmasını kullanmaktır.

import DoStuff.py as DS
DS.main()

Unutma içeri aktarım dosyası olduğunu OLMALIDIR .py uzantılı adında


3
Buradan import DoStuff.py as DSiçe aktarma girişiminde bulunmaz mıydınız ? pyDoStuff
Benj

5

Bu notu başka bir yerde çok açık bir şekilde ifade etmediğimi eklemek istiyorum; bir modülün / paketin içinde, dosyalardan yüklenirken modül / paket adının önüne mymodule. Bunun mymodulegibi bir düzen olduğunu düşünün :

/main.py
/mymodule
    /__init__.py
    /somefile.py
    /otherstuff.py

Ne zaman yükleme somefile.py/ otherstuff.pydan __init__.pyiçerikleri gibi görünmelidir:

from mymodule.somefile import somefunc
from mymodule.otherstuff import otherfunc

2

Almak istediğiniz modülün bir alt dizinde olmaması durumunda, aşağıdakileri deneyin ve app.pyen derin ortak ana dizinden çalıştırın :

Dizin Yapısı:

/path/to/common_dir/module/file.py
/path/to/common_dir/application/app.py
/path/to/common_dir/application/subpath/config.json

İçinde app.py, istemcinin yolunu sys.path dosyasına ekleyin:

import os, sys, inspect

sys.path.append(os.getcwd())
from module.file import MyClass
instance = MyClass()

İsteğe bağlı (örn. Yapılandırmalar yüklerseniz) (Inspect kullanım durumlarım için en sağlam olanı gibi görünüyor)

# Get dirname from inspect module
filename = inspect.getframeinfo(inspect.currentframe()).filename
dirname = os.path.dirname(os.path.abspath(filename))
MY_CONFIG = os.path.join(dirname, "subpath/config.json")

Çalıştırmak

user@host:/path/to/common_dir$ python3 application/app.py

Bu çözüm benim için CLC ve PyCharm'da işe yarıyor.


2

Python betiğinizi abc.py adıyla eklemenin birkaç yolu vardır.

  1. Örneğin, dosyanız abc.py (import abc) olarak adlandırılırsa, sınırlama, dosyanızın çağıran python betiğinizle aynı konumda bulunmasıdır.

abc içe aktar

  1. örneğin, python dosyanız Windows klasörünün içindeyse. Windows klasörü, çağıran python betiğinizle aynı konumda bulunur.

klasör içe aktarma abc

  1. Incase abc.py komut dosyası iç klasörde bulunan içeriden internal_folder

klasör.internal_folder içe aktarma abc

  1. Yukarıda James tarafından yanıtlandığı gibi, dosyanızın sabit bir konumda olması durumunda

import os
import sys
scriptpath = "../Test/MyModule.py"
sys.path.append (os.path.abspath (scriptpath))
içe aktarma MyModule

Python betiğinizin güncellenmesi ve yüklemek istemiyorsanız - otomatik yenileme için bu ifadeleri kullanın. Bonus :)

%load_ext autoreload 
%autoreload 2

1

Python dosyasını başka bir python dosyasına içe aktarmak için

diyelim ki bir görüntüleme işlevi olan helper.py python dosyası var,

def display():
    print("I'm working sundar gsv")

Şimdi app.py dosyasında , görüntüleme işlevini kullanabilirsiniz,

import helper
helper.display()

Çıktı,

I'm working sundar gsv

NOT: .py uzantısını belirtmenize gerek yoktur.


1

Bu çılgınca gelebilir, ancak yalnızca bir sarmalayıcı komut dosyası oluşturuyorsanız içe aktarmak istediğiniz dosyaya sembolik bir bağlantı oluşturabilirsiniz.


1

Bunu da yapabilirsiniz: from filename import something

örnek: from client import Client Uzantıya ihtiyacınız olmadığını unutmayın .py .pyw .pyui.


1

Ben herhangi bir işlevi çağırmak için esnek bir python dosyasından bir işlevi çağırmak için bu şekilde yaptım.

import os, importlib, sys

def callfunc(myfile, myfunc, *args):
    pathname, filename = os.path.split(myfile)
    sys.path.append(os.path.abspath(pathname))
    modname = os.path.splitext(filename)[0]
    mymod = importlib.import_module(modname)
    result = getattr(mymod, myfunc)(*args)
    return result

result = callfunc("pathto/myfile.py", "myfunc", arg1, arg2)

Yeni bir işlevi, doğrudan işlevi kullanmaktan daha iyi yapmak nasıl?
qwr

@ qwr Yeni işlev callfunc (), python dosyasındaki hedef işlevi dinamik olarak çağırmak için kodun bir paketidir. Verilen örnek "pathto / myfile.py" python dosyasındaki "myfunc" hedefidir. "İşlevi doğrudan kullanma" ile ne demek istiyorsun?
Xiao-Feng Li

Benim için mükemmel çalıştı. Örneğimde: from mypath import Pathile değiştirdim Path = callfunc("/folder/to/mypath.py", "Path"). Teşekkürler @ Xiao-FengLi
user319436

@ user319436 Cevabım nihayet birine yardımcı olur. :)
Xiao-Feng Li

Teşekkürler xiao-feng-li !! Mükemmel cevap!!
Altieres de Matos

0

Yukarıda listelendiği gibi birçok yol var, ama ben sadece bir dosyanın içeriğini almak istiyorum ve satır ve satır yazmak ve diğer modülleri almak zorunda istemiyorum . Bu yüzden, file.propertyiçe aktarılan dosyayı kendinizle birleştirmenin aksine , nokta sözdizimiyle ( ) bile bir dosyanın içeriğini almanın bir yolunu buldum .
Her şeyden önce, içe aktaracağım dosyam,data.py

    testString= "A string literal to import and test with"


Not: Bunun .txtyerine uzantıyı kullanabilirsiniz .
Gelen mainfile.py, açma ve içeriğini alarak başlayın.

    #!usr/bin/env python3
    Data=open('data.txt','r+').read()

Şimdi içeriğe bir dize olarak sahipsiniz, ancak erişmeye çalışmak , sınıfın bir örneği data.testStringgibi bir hataya neden olacak ve bir özelliğe sahip olsa bile, beklediğinizi yapmayacaktır. Sonra bir sınıf oluşturun. Örneğin (kelime oyunu),datastrtestString
ImportedFile

    class ImportedFile:

Ve bunu içine koyun (uygun girinti ile):

    exec(data)


Ve son olarak şu şekilde yeniden atayın data:

    data=ImportedFile()

Ve bu kadar! Diğer herhangi bir modül için yaptığınız gibi erişin, yazmak print(data.testString)konsola yazdırılacaktır A string literal to import and test with.
Ancak, eşdeğeri from mod import *sınıfı düşürmek, örnek ataması yapmak ve eşdeğerini kaldırmak istiyorsanız exec.

Umarım bu yardımcı olur :)
-Benji


Dosyanın içeriğini bir dize olarak okumayı ve sonra yürütmek, insanların gönderdiği tüm diğer çözümlere sahip olduğumuzda iyi bir çözüm olduğunu mu düşünüyorsunuz?
qwr

@qwr Erm evet, biliyorum. Diğer cevapların çoğu bazı durumlarda işe yaramaz. Bu yüzden çalışmayı garantileyen kolay bir yola ihtiyacım vardı. Annelerin bakış açısından bir şeyleri göremiyorsanız, resmi IDLE'yi kullanmayı denemeniz gerekir.
Benj

0

Python'un çok bilinmeyen bir özelliği, zipdosyaları içe aktarma yeteneğidir :

library.zip
|-library
|--__init__.py

__init__.pyPaketin dosyası aşağıdakileri içerir:

def dummy():
    print 'Testing things out...'

Zip arşivinden bir paketi içe aktarabilen başka bir komut dosyası yazabiliriz. Yalnızca zip dosyasını sys.path dosyasına eklemek gerekir.

import sys
sys.path.append(r'library.zip')

import library

def run():
    library.dummy()

run()

zip dosyası ne fayda sağlar?
qwr
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.