Soru Paket Alt Dizinindeki Python Access Verileri


Veri dosyalarını açmaya ihtiyaç duyan modüller içeren bir python paketi yazıyorum. ./data/ alt dizin. Şu anda sınıflarıma ve işlevlerime kodlanmış dosyalara giden yollara sahibim. Kullanıcının sisteminde nereye kurulduğuna bakılmaksızın alt dizine erişebilen daha sağlam bir kod yazmak istiyorum.

Çeşitli yöntemler denedim, ama şimdiye kadar hiç şansım olmadı. "Geçerli dizini" komutlarının çoğunun, modülün dizinini değil, sistemin python yorumlayıcısının dizinini döndürdüğü görülüyor.

Bu önemsiz, ortak bir sorun olması gerektiği gibi görünüyor. Yine de bunu anlayamıyorum. Problemin bir kısmı veri dosyamın değil .py dosyaları, bu yüzden içe aktarma işlevlerini ve benzerlerini kullanamıyorum.

Baska öneri?

Şu an paket dizinim şöyle görünüyor:

/
__init__.py
module1.py
module2.py
data/   
   data.txt

Erişmeye çalışıyorum data.txt itibaren module*.py

Teşekkürler!


76
2018-04-22 22:17


Menşei


Ayrıca bakınız: Python paketinin içinden (statik) bir dosya nasıl okunur? - Martin Thoma


Cevaplar:


Alt çizgi altçizgi dosyası altçizgi alt çizgi kullanabilirsiniz.__file__) paketin yolunu almak, bunun gibi:

import os
this_dir, this_filename = os.path.split(__file__)
DATA_PATH = os.path.join(this_dir, "data", "data.txt")
print open(DATA_PATH).read()

23
2018-04-22 22:37



Dosyalar bir dağıtımda ise (IE. Yumurta) bu çalışmaz. Veri dosyasına ulaşmak için pkg_resources kullanın. - Chris
Gerçekten, bu kırık. - Federico
Ayrıca, __file__ değer, zip dosyasına giden yol olacak şekilde py2exe ile çalışmaz. - Pod


Bunu yapmanın standart yolu, setuptools paketleri ve pkg_resources ile yapılır.

Paketinizi aşağıdaki hiyerarşiye göre düzenleyebilir ve bu bağlantıya göre, veri kaynaklarınızı veri kaynaklarına yönlendirecek şekilde paket kurulum dosyasını yapılandırabilirsiniz:

http://docs.python.org/distutils/setupscript.html#installing-package-data

Bu bağlantıya göre, bu dosyaları pkg_resources kullanarak yeniden bulabilir ve kullanabilirsiniz:

http://peak.telecommunity.com/DevCenter/PkgResources#basic-resource-access

import pkg_resources

DATA_PATH = pkg_resources.resource_filename('<package name>', 'data/')
DB_FILE = pkg_resources.resource_filename('<package name>', 'data/sqlite.db')

109
2018-04-08 23:42



Bunun tercih edilen yol olduğunu düşünüyorum, nedenlerden tam olarak emin değilim, ancak paket / modüle başvurduğunuzda projeler uyarı veriyor __file__. - lukecampbell
Alışkanlık pkg_resources çalışma zamanı bağımlılığı oluşturmak setuptools? Örneğin, bir Debian paketini yeniden dağıtayım, o yüzden neden güvenirim python-setuptools sadece bunun için? Şimdiye kadar __file__ benim için iyi çalışıyor. - mlt
Neden bu daha iyidir: ResourceManager sınıfı, paket kaynaklarına tek tip erişim sağlar, bu kaynaklar dosya ve dizinler olarak mevcut olsun veya bir çeşit arşivde sıkıştırılmış olsun - vrdhn
Parlak öneri, teşekkürler. Kullanarak açık standart bir dosya uyguladım from pkg_resources import resource_filename open(resource_filename('data', 'data.txt'), 'rb') - niallsco
Bu, kurulmadığı zaman paketi nasıl kullanacak? Sadece yerel olarak test ediyorum demek istedim - Claudiu


Bugün çalışan bir çözüm sağlamak. Tüm bu tekerlekleri yeniden icat etmek için kesinlikle bu API'yi kullanın.

Gerçek bir dosya sistemi dosya adı gereklidir. Sıkıştırılmış yumurta bir önbellek dizinine çıkarılacak:

from pkg_resources import resource_filename, Requirement

path_to_vik_logo = resource_filename(Requirement.parse("enb.portals"), "enb/portals/reports/VIK_logo.png")

Belirtilen kaynak için okunabilir dosya benzeri bir nesne döndürün; gerçek bir dosya, bir StringIO veya benzeri bir nesne olabilir. Akış, "bayt modda", kaynakta baytların bulunduğu her şeyin olduğu gibi okunacağı anlamındadır.

from pkg_resources import resource_stream, Requirement

vik_logo_as_stream = resource_stream(Requirement.parse("enb.portals"), "enb/portals/reports/VIK_logo.png")

Pkg_resources kullanarak Paket Bulma ve Kaynak Erişimi


12
2017-10-09 12:33





Sanırım bir cevabı buldum.

Aşağıdakileri içeren diğer modüllere aktardığım bir data_path.py modülü yapıyorum:

data_path = os.path.join(os.path.dirname(__file__),'data')

Ve sonra tüm dosyalarımı

open(os.path.join(data_path,'filename'), <param>)

6
2018-04-22 22:35



Bu, kaynak bir arşiv dağıtımında (sıkıştırılmış yumurta gibi) çalışırken işe yaramaz. Böyle bir şey tercih et: pkg_resources.resource_string('pkg_name', 'data/file.txt') - ankostis
@ankostis setuptools, kullandığınızı algılarsa arşivi ayıklamaya yetecek kadar akıllıdır __file__ yere. Benim durumumda, gerçekten yolları ve akışları olmayan bir kütüphane kullanıyorum. Tabii ki dosyaları diske geçici olarak yazabilirim ama tembel olmak için sadece setuptools'un özelliğini kullanıyorum. - letmaik


Tüm modülünüz için bir adaya ihtiyacınız var, dizin ağacına verildikten sonra bu ayrıntıyı listelemezsiniz, benim için bu işe yaradı:

import pkg_resources
print(    
    pkg_resources.resource_filename(__name__, 'data/data.txt')
)

Fark edilmeyen kurulum dosyaları, paketlenmiş veri dosyalarıyla bir ad eşleşmesine dayalı dosyaları çözümlemek için görünmüyor. data/ önek hemen hemen ne olursa olsun. Kullanabilirsiniz os.path.join('data', 'data.txt) Alternatif dizin ayırıcılarına ihtiyacınız varsa, genelde sabit kodlanmış unix stili dizin ayırıcılarıyla uyumluluk sorunu bulamıyorum.


5
2017-12-10 09:59



docs.python.org/3.6/distutils/... > Kurulum komut dosyasında sağlanan herhangi bir yol adının (dosya veya dizin) Unix kongresi, yani eğik olarak ayrılmış kullanılarak yazılması gerektiğini unutmayın. Distutils, bu platform-tarafsız gösterimi, gerçekte yol adını kullanmadan önce geçerli platformunuza uygun olan her şeye dönüştürmeye özen gösterir. Bu, kurulum komut dosyanızın işletim sistemleri arasında taşınabilir olmasını sağlar. Bu da şüphelerin temel hedeflerinden biridir. Bu ruhta, bu belgedeki tüm yol adları kesiktir. - changyuheng