Python dosyalarını yapılandırma dosyaları olarak kullanmak bir fikrin ne kadar kötü?


72

Her zaman uygulamalarımı yapılandırmak için JSON dosyalarını kullandım . Onları bir çok Java kodladığımda kullanmaya başladım ve şimdi esas olarak sunucu tarafı ve veri bilimi Python geliştirme üzerine çalışıyorum ve JSON'un daha doğru bir yol olup olmadığından emin değilim .

Kerevizin yapılandırma için gerçek Python dosyalarını kullandığını gördüm. Başlangıçta bu konuda şüpheci oldu. Ancak yapılandırma için basit Python veri yapılarını kullanma fikri benim üzerimde büyümeye başlıyor. Bazı artılar:

  • Veri yapıları normalde kodladığım ile aynı olacaktır. Bu nedenle, zihin çerçevesini değiştirmeme gerek yok.
  • IDE'm (PyCharm) yapılandırma ve kod arasındaki bağlantıyı anlıyor. Ctrl+ Bkonfigürasyon ve kod arasında kolayca geçiş yapmayı mümkün kılar.
  • IMO ile gereksiz katı JSON ile çalışmama gerek yok . Sana çift tırnak işareti, izleyen virgül yok ve yorum yok.
  • Üzerinde çalışmakta olduğum uygulamada test konfigürasyonları yazabiliyorum, daha sonra herhangi bir dönüştürme ve JSON ayrıştırması yapmak zorunda kalmadan kolayca bir konfigürasyon dosyasına taşıyabiliyorum.
  • Gerçekten gerekliyse, yapılandırma dosyasında çok basit bir komut dosyası yapmak mümkündür. (Her ne kadar bu çok sınırlı olsa da)

Öyleyse sorum şu: Geçiş yaparsam, kendimi ayağımdan nasıl vurabilirim?

Hiçbir vasıfsız son kullanıcı yapılandırma dosyalarını kullanmayacaktır. Yapılandırma dosyalarında yapılan değişiklikler şu anda Git’e aittir ve sürekli dağıtımın bir parçası olarak sunucularımıza yayılır. Acil bir durum söz konusu olmadıkça veya geliştirilmediği sürece manuel yapılandırma değişikliği yoktur.

(Ben kabul ettik YAML , ama bu konuda bir şey şimdi Amerikan masadan olduğu için, Yani. Beni rahatsız ediyor.)


39
Beceriksiz senin sorunun değil. Kötü niyetli.
Blrfl

9
"Amerikan masa dışı" derken ne demek istiyorsun ?
Peter Mortensen

24
"Öyleyse, şimdilik Amerikan masasının dışında." === "Yani şimdilik, Amerikalıların dediği gibi, masadan kalkıyor."
Piskopos

7
JSON'dan hoşlanmıyorsanız, yaml'i denemelisiniz. Yapılandırma için çok seviyorum. özellikle daha büyük dizeler söz konusu olduğunda, YAML JSON'dan daha okunabilir durumdadır.
Christian Sauer

5
bishop ingilterede ingilizcede "masadan çıkmayan" artık dikkate alınmadığı anlamına gelir; tartışıldığı zaman başvuru için başvurmak için avam meclisinin ortasındaki masanın üzerine konulan parlamento hareketleri, dolayısıyla 'tartışma için masaya dökülür' (meclis kayıtları 1799 - books.google.com.tr/… ), AFAIK’ın ABD’nin anlamı aynı, fakat meclinizde bir masa olup olmadığını bilmiyorum.
Pete Kirkham

Yanıtlar:


92

Bir yapılandırma dosyası yerine bir komut dosyası dili kullanmak, ilk bakışta harika görünüyor: bu dilin tam gücüne sahip ve basitçe eval()ya importda basitçe . Uygulamada, birkaç gotcha var:

  • öğrenilmesi gereken bir programlama dilidir. Konfigürasyonu düzenlemek için bu dili yeterince iyi bilmeniz gerekir. Konfigürasyon dosyaları genellikle yanlış anlaşılması daha zor olan daha basit bir biçime sahiptir.

  • bu bir programlama dilidir, yani config hata ayıklamak zorlaşabilir. Normal bir config dosyası ile ona bakar ve her özellik için hangi değerlerin sağlandığını görürsünüz. Bir komut dosyasıyla, değerleri görmek için önce onu çalıştırmanız gerekir.

  • yapılandırma ile gerçek program arasında net bir ayrım yapılmasını zorlaştıran bir programlama dilidir. Bazen bu tür bir genişletilebilirlik istersiniz, ancak bu noktada büyük olasılıkla gerçek bir eklenti sistemi arıyorsunuz.

  • bir programlama dilidir, yani config programlama dilinin yapabileceği her şeyi yapabilir. Bu yüzden ya dilin esnekliğinin çoğunu yok eden bir sanal alan kullanıyorsunuz ya da config yazarına büyük güven duyuyorsunuz.

Bu nedenle, eğer aracınızdaki kitle geliştiriciler ise, örneğin Sphinx config ya da Python projelerinde setup.py gibi yapılandırma için bir betik kullanılması uygun olabilir. Çalıştırılabilir konfigürasyona sahip diğer programlar Bash gibi kabuklar ve Vim gibi editörlerdir.

Yapılandırma için birçok koşullu bölüm içeriyorsa veya geri aramalar / eklentiler sağlıyorsa, yapılandırma için bir programlama dili kullanmak gerekir. Eval () yerine doğrudan bir komut dosyası kullanmak - bazı config alanları kullanmak daha fazla hata ayıklamaya meyillidir (yığın izlerini ve satır numaralarını düşünün!).

Eğer doğrudan bir programlama dili kullanmak, eğer konfigürasyonunuz konfigürasyonu otomatik olarak oluşturmak için betikler yazdığınız kadar tekrarlayıcı ise de iyi bir fikir olabilir. Fakat belki yapılandırma için daha iyi bir veri modeli bu kadar açık bir yapılandırma ihtiyacını ortadan kaldırabilir mi? Örneğin, config dosyasının daha sonra genişleteceğiniz yer tutucuları içermesi yararlı olabilir. Bazen görülen başka bir özellik, kendi kendine bazı problemleri ortaya çıkarsa da, birbirlerini geçersiz kılabilecek farklı önceliğe sahip çoklu konfigürasyon dosyalarıdır.

Çoğu durumda, INI dosyaları, Java özellik dosyaları veya YAML belgeleri yapılandırma için çok daha uygundur. Karmaşık veri modelleri için, XML de uygulanabilir. Sizin de belirttiğiniz gibi, JSON, iyi bir veri alışverişi biçimi olmasına rağmen, onu insan tarafından düzenlenebilir bir yapılandırma dosyası olarak uygun kılmayan bazı özelliklere sahiptir.


25
En ünlüsü "yanlışlıkla Turing-complete" olan birkaç yapılandırma dosyası formatı vardır sendmail.cf. Bu, gerçek bir betik dili kullanmanın , bunun gerçekten Turing-tamamlanmak üzere tasarlandığından faydalı olabileceğini gösterir . Ancak , Turing-tamlık ve "Tetris-tamlık" iki farklı şeydir ve süre sendmail.cfkeyfi fonksiyonları hesaplayabilir, bu olabilir değil adresten gönder /etc/passwdPython veya Perl mümkün olacaktır, hangi sabit diskinizde net üzerinden veya biçimlendirmek.
Jörg W Mittag

3
@ JörgWMittag Torino tamamlama özelliği ağ üzerinden bir şeyler gönderebilmek veya sabit diske erişmek anlamına gelmez. Yani, Turin tamamlama işlemi G / Ç ile ilgili olmayan işleme ile ilgilidir. Örneğin, CSS, Torino'nun tamamlandığı düşünülür, ancak kalıcı depolama alanınızla uğraşmaz. Başka bir yerde "İdris tamamen saf işlevsel bir dil, bu yüzden tanım olarak Turing-complete değil" demiştiniz, takip etmiyor ve görünüşe göre Turin tamamlandı. Testris-complete'ı kullandığınıza, dilin Turin'in eksiksiz olduğu, ancak tam G / Ç yapamayacağınız anlamına geldiğine ikna olmuştum ... göründüğü gibi değil.
Theraot

6
@Theraot: "Toplam", her zaman geri döndüğü anlamına gelir. Bir Turing Makinesi sonsuz bir döngü gerçekleştirebilir, yani geri dönme yeteneğine sahiptir. Ergo, İdris bunun demektir Turing Makinası yaptığı her şeyi, yapamaz değil Turing tamamlama. Bu bağımlı olarak yazılmış tüm diller için geçerlidir. Bağımlı olarak yazılmış bir dilin amacı programlarla ilgili keyfi özelliklere karar verebilmenizdir, oysa Turing-eksiksiz bir dilde "bu program durur mu?" Gibi önemsiz özelliklere bile karar veremezsiniz. Toplam diller tanımı gereğidir , çünkü Turing Makineleri kısmidir.
Jörg W Mittag

10
Tanımı "Turing tamamlama" nin "Bir Turing makinesi uygulayabilir" dir. "Tetris-complete" tanımı "Tetris'i uygulayabilir" dir. Bu tanımın tek amacı, Turing'in bütünlüğünün gerçek dünyada pek de ilginç olmadığıdır. Turing-tamamlanmayan birçok yararlı dil var; örneğin, HTML, SQL (1999 öncesi), çeşitli DSL'ler, vb. OTOH, Turing-tamamlama, yalnızca doğal sayılarla işlevleri hesaplayabileceğiniz anlamına gelir; ekrana yazdırma, ağa erişme, kullanıcıyla, işletim sistemiyle, çevre ile etkileşimi, hepsi önemlidir.
Jörg W Mittag

4
Edwin Brady'nin bu örneği kullanmasının nedeni, birçok insanın Turing-tamamlanmayan dillerin genel amaçlı programlama için kullanılamayacağını düşünmesidir. Ben de böyle düşünürdüm, çünkü sonuçta, birçok ilginç programın temelde durmak istemediğimiz sonsuz döngüler olduğunu , örneğin sunucular, işletim sistemleri, bir GUI'deki olay döngüleri, oyun döngüleri olduğunu düşünürdüm. Birçok program sonsuz veriyi işler, örneğin olay akışları. Bunu toplam bir dilde yazamayacağınızı düşünürdüm, ancak yapabileceğinizi öğrendim ve bu yüzden bu yetenek için bir terim edinmenin iyi bir fikir olduğunu düşünüyorum.
Jörg W Mittag

50

Amon'un cevabındaki her şeye +1 . Bunu eklemek isterim:

Aynı yapılandırmayı farklı bir dilde yazılmış kodun içinden içe aktarmak istediğinizde Python kodunu yapılandırma diliniz olarak kullanmaktan pişman olacaksınız. Örneğin, projenizin bir parçası olan ve C ++ veya Ruby'de yazılmış bir kod veya başka bir şeyin yapılandırmayı çekmesi gerekiyorsa, Python yorumlayıcısını bir kütüphane olarak bağlamanız veya yapılandırmayı her ikisi de bir Python işleminde ayrıştırmanız gerekir. hangi garip, zor veya yüksek yükü vardır.

Bugün bu yapılandırmayı içe aktaran kodun tümü Python'da yazılabilir ve bunun yarın da doğru olacağını düşünebilirsiniz, ancak kesin olarak biliyor musunuz?

Konfigürasyonunuzda mantıklı (statik veri yapıları dışında herhangi bir şey) kullanacağınızı söylemiştiniz, ki bu iyi, ancak bunun herhangi bir kısmı varsa, gelecekte bunu geri almakta zorlanacaksınız. bildirimsel bir yapılandırma dosyasına geri dönebilir.

Kayıt için DÜZENLEME : Birkaç kişi bu cevaba, bir projenin başka bir dilde başarıyla yeniden yazılmasının ne kadar muhtemel veya olası olmadığına dair yorum yaptı. Geriye tam uyumlu bir yeniden yazmanın muhtemelen nadiren görüldüğünü söylemek doğru olmaz. Aslında aklımda olan, aynı projenin bitleri ve parçalarıydı (ve aynı yapılandırmaya erişmeleri gerekiyordu) farklı dillerde yazılmışlardı. Örneğin, hız için C ++ 'da yığın, Python'da toplu veritabanı temizliği, bazı kabuk betikleri tutkal olarak kullanılır. Öyleyse bu dava için de bir düşünce :)


1
@Mast, özür dilerim ama ben takip etmiyorum. Dosyanın adı (.py ile bitip bitmediğine bakılmaksızın) burada ya da burada değil. Yapmaya çalıştığım nokta Python'da yazılmışsa okumak için bir Python yorumlayıcısına ihtiyacınız var.
Celada

12
@Mast Sanırım yanlış ayrıştırıyorsunuz. Bu cevaptan aldığım nokta (hem orjinal hem de düzenlenmiş), bir programlama dilinde konfigürasyon dosyaları yazma seçiminin başka bir dilde kod yazmayı zorlaştırmasıdır. Örneğin, uygulamanızı Anrdoid / iPhone'a taşımaya karar veriyorsunuz ve başka bir dil kullanıyor olacaksınız. Ya (a) cep telefonu uygulamasındaki bir Python yorumlayıcısına güvenmek zorundasınız (ideal değil), (b) yapılandırmayı dile bağımsız bir biçimde tekrar yazmalı ve kullanılan Python kodunu yeniden yazmalı ya da (c) bakımını yapmalısınız. iki yapılandırma formatı ileriye gidiyor.
Jon Bentley

4
@JonBentley Çok dilli projeler yapmayı planlıyorsanız endişenin ilgili olacağını düşünüyorum. OP'den bu izlenimi alamadım. Ek olarak, config için metin dosyalarını kullanmak hala değerlerin gerçek ayrıştırılması / dönüştürülmesi için ek kod gerektirir (tüm dillerde). Teknik olarak, Python tarafını key=valueconfig atamalarıyla sınırlıyorlarsa, bir Java / C ++ programının neden Python dosyasını düz metin dosyası olarak okuyamadığını ve başka bir şeye geçmeleri gerektiğinde bunları ayrıştırmadığını anlamıyorum. gelecek. Tam teşekküllü bir Python tercümana ihtiyaç duymuyorum.
code_dredd

3
@ray Doğru, ancak cevap, soruların yalnızca onları gönderen kişiye uygulanmaması gerektiği temelinde faydalıdır. Standart bir format kullanırsanız (örneğin INI, JSON, YAML, XML, vb.), Muhtemelen kendiniz yazmak yerine mevcut bir ayrıştırma kütüphanesini kullanıyor olacaksınız. Bu, ayrıştırma kütüphanesiyle arabirim oluşturmak için yalnızca bir adaptör sınıfına yapılan ek işi azaltır. Kendinizi key = value ile sınırlandırıyorsanız, bu OP'nin Python'u en başta kullanma nedenlerinin çoğunu ortadan kaldırır ve tanınmış bir formata sahip olabilirsiniz.
Jon Bentley

3
Bunu birkaç yıl önce Lua'da yazılmış bir araç Lua komut dosyasını konfigürasyonları olarak kullandığında bunu yapmam gerekiyordu, sonra C # dilinde yeni bir araç yazmamızı istediler ve özellikle Lua config komut dosyasını kullanmamızı istediler. Programlanabilir ve basit olmayan x = y olmak üzere toplam 2 satırları vardı, fakat .net için açık kaynaklı Lua tercümanları hakkında bilgi edinmek zorunda kaldım. Bu tamamen teorik bir argüman değil.
Kevin Fee

21

Diğer cevaplar zaten çok iyi, sadece birkaç projede gerçek dünya kullanım deneyimimi getireceğim.

Artıları

Onlar çoğunlukla zaten yazıldığından:

  • Python programındaysanız, ayrıştırma bir esintidir ( eval); o (Programımızda, biz / dampingli aracılığıyla gayet yüklenen geometrik puan ve dönüşümler var daha da karmaşık veri türleri için otomatik olarak çalışır repr/ ' eval);
  • sadece birkaç kod satırıyla bir "sahte config" oluşturmak önemsizdir;
  • daha iyi yapılara sahipsiniz ve IMO, JSON'dan çok daha iyi bir sözdizimine sahip (cümle sadece yorumlarda bulunmak ve sözlük anahtarlarının etrafında çift tırnak koymak zorunda kalmamak büyük bir okunabilirlik kazancıdır).

Eksileri

  • kötü niyetli kullanıcılar ana programınızın yapabileceği her şeyi yapabilir; Genelde bir kullanıcı, uygulamanın yapabileceği her şeyi yapabileceği bir yapılandırma dosyasını değiştirebiliyorsa;
  • Artık bir Python programında değilseniz, şimdi bir sorununuz var. Konfigürasyon dosyalarımızdan bazıları orijinal uygulamalarına özel kalırken, birçoğu şu anda çoğu C ++ olan ve şu anda kötü tanımlanmış bir küçük kişi için bir araya getirilmiş ayrıştırıcıya sahip birkaç farklı program tarafından kullanılan bilgileri depolamak için geldi. Python'un alt kümesi repr. Bu belli ki kötü bir şey.
  • Programınız Python'da kalsa bile, Python sürümünü değiştirebilirsiniz. Diyelim ki başvurunuz Python 2'de başladı; Çok sayıda testten sonra Python 3'e geçirmeyi başardınız - ne yazık ki, tüm kodunuzu gerçekten test etmediniz - müşterilerinizin makinelerinde Python 2 için yazılan ve üzerinde yaptığınız tüm konfigürasyon dosyalarına sahipsiniz. Gerçekten kontrolü yok. Python 2 tercümanını bir araya getirmek / çağırmak istemediğiniz sürece, eski yapılandırma dosyalarını (genellikle dosya formatları için yapılır) okumak için "uyumluluk modu" bile sağlayamazsınız!
  • Python'da olsanız bile , yapılandırma dosyasını koddan değiştirmek gerçek bir sorundur, çünkü ... peki, kodu değiştirmek önemsiz değildir, özellikle de zengin bir sözdizimi olan ve LISP veya benzeri olmayan bir kod. Bizimkilerden biri program aslında elle yazılmış Python, bir yapılandırma dosyası vardır, ancak daha sonra (belli bir ayardır şeylerin bir listesi yazılım aracılığıyla manipüle etmek faydalı olacaktır çıktı hangi yolu bir GUI kullanarak yeniden düzenlemek için basit). Bu büyük bir problem, çünkü:

    • yalnızca bir ayrıştırma işlemi gerçekleştirse bile → AST → tekrar yazma dönüşü önemsiz değildir (önerilen çözümlerin yarısının daha sonra "eski, kullanmayın, her durumda çalışmadığını" olarak işaretleyin);
    • Çalışsalar bile, AST çok düşük seviyededir; genellikle dosyada gerçekleştirilen hesaplamaların sonucunu değiştirmekle ilgilenirsiniz , ona atılan adımları değil;
    • bu da bizi ilgilendiğiniz değerleri düzenleyememenizin basit bir gerçeğine getiriyor, çünkü kodunuzda anlayamayacağınız / işleyemeyeceğiniz bazı karmaşık hesaplamalarla üretilebilirler.

    Bunu, bellekteki temsilin her zaman veri kaybı olmadan düzenlenip yazılabildiği JSON, INI veya (Tanrı korusun!) XML ile karşılaştırın (çoğu DOM ayrıştırıcısının metin boşluklarında ve yorum düğümlerinde boşluk tutabildiği XML) veya en azından sadece bir miktar format kaybediyor (JSON, formatın kendisi okuduğunuz ham veriden daha fazlasına izin vermiyor).


Yani, her zamanki gibi net bir çözüm yok; konuyla ilgili mevcut politikam şudur:

  • yapılandırma dosyası şuysa:

    • kesinlikle bir Python uygulaması için ve buna özel - kesinlikle, başka hiç kimse ondan okumaya çalışmaz;
    • elle yazılmış;
    • güvenilir bir kaynaktan gelen;
    • Hedef uygulama veri türlerini kullanmak gerçekten çok önemlidir;

    Python dosyası olabilir , geçerli bir fikir olabilir;

  • eğer öyleyse:

    • ondan başka bir uygulamanın okunması olasılığı olabilir;
    • Bu dosyanın bir uygulama tarafından düzenlenmesi ihtimali vardır; muhtemelen benim uygulamamın kendisi de;
    • güvenilmeyen bir kaynak tarafından sağlanır.

    "sadece veri" formatı daha iyi bir fikir olabilir.

Tek bir seçim yapmak gerekmediğine dikkat edin - Son zamanlarda her iki yaklaşımı kullanan bir uygulama yazdım. Güzel bir Python ikramiyesine sahip olmanın avantajlarının bulunduğu ilk kurulum, el yazısı ayarları olan neredeyse hiç değiştirilmemiş bir dosyama ve kullanıcı arayüzünden düzenlenen yapılandırma için bir JSON dosyasına sahibim.


1
config oluşturma veya yeniden yazma hakkında çok iyi bir nokta! Ancak, XML dışındaki birkaç format, yapılandırma için son derece önemli olduğunu düşündüğüm çıktıdaki yorumları alabilir. Diğer biçimler bazen note:yapılandırma için göz ardı edilen bir alanı da beraberinde getirir.
amon

2
"Bir kullanıcı bir yapılandırma dosyasını değiştirebiliyorsa, uygulama yapabileceklerini zaten yapabilir" - bu tam olarak doğru değildir. Pastebin'e yüklediğiniz tanımadığınız birisinin parlak config dosyasından daha sınamaya ne dersiniz?
Dmitry Grigoryev

2
@DmitryGrigoryev: Eğer o hedefe nişan alıyorsanız, kurbanınıza bazılarını kopyalayıp yapıştırmalarını da söyleyebilirsiniz, curl ... | bashdaha da zahmetsizdir. :-P
Matteo Italia

@DryryGrigoryev: ve bu, bir kişinin bir iş sistemini üretim gününde tamamen mahvetmesine izin verebilecek bir şey. Eğer 'eval' sizin çözümleyicinizse, bu okunmadan önce problemleri kontrol etmek için fırsatın olmadığı anlamına gelir. (Kabuk komut dosyalarının üretimde bu kadar kötü olmasının nedeni aynı). INI, YAML veya JSON bu konuda güvenlidir.
Joe

1
@DmitryGrigoryev: Demek istediğim, eğer mağdur türünüz bir konfigürasyon dosyasını körü körüne kopyalayıp yapıştırmak için yeterince aptalsa, muhtemelen makinelerinde ne olursa olsun yapması için onu daha az eğik yöntemle kandırabilmenizdir ("bunu bir konsola yapıştırın" Sorununu çöz! "). Ayrıca, çalıştırılamayan konfigürasyon dosyalarında bile zarar verme potansiyeli çok yüksektir - kritik dosyalara kötü niyetli olarak giriş yapmak bile (uygulama yeterli yetkiyle çalışıyorsa) sisteme zarar verebilir. Ben pratikte o kadar zor olmadığını düşünüyorum yüzden sebebidir çok güvenlik açısından bir fark.
Matteo Italia

8

Asıl soru şudur: Konfigürasyon dosyanızın bazı Turing dillerinde (Python gibi) olmasını ister misiniz? Bunu istiyorsun, ayrıca bazı gömme düşünebilirsiniz diğer benzeri (Turing tam) kodlama dili Guile veya Lua bölümünü okumak; "daha basit" kullanmak veya Python olandan, gömmek için orada algılanabilecek çünkü ( Genişletme & Python Katıştırma ). Bunu daha fazla tartışmayacağım (çünkü Amon tarafından verilen diğer cevaplar - bunu derinlemesine tartıştım) ancak uygulamanıza bir betik dili yerleştirmenin çok erken düşünmeniz gereken önemli bir mimari seçim olduğuna dikkat edin.; Bu seçimi daha sonra yapmayı gerçekten tavsiye etmiyorum!

"Scriptler" ile yapılandırılabilen bir programın iyi bilinen bir örneği GNU emacs editörüdür (veya özel mülkiyette AutoCAD ); bu nedenle komut dosyası kabul ederseniz, bazı kullanıcıların sonunda sizin açınızdan ve belki de kötüye kullanmaya başladığına göre, bu tesisi kapsamlı bir şekilde kullanacağını ve çok bin satırlık bir komut dosyası oluşturacağını; bu nedenle, yeterince iyi bir kodlama dili seçimi önemlidir.

Bununla birlikte (en azından POSIX sistemlerinde), "dosya" yapılandırmasının başlatma sırasında dinamik olarak hesaplanabilmesini (tabii ki, aklı başında bir konfigürasyonun yükünü sistem yöneticinize veya kullanıcıya bırakarak) etkinleştirmek için uygun olduğunu düşünebilirsiniz. bir dosyadan veya bir komuttan gelen metin ) Bunun için, örneğin a veya a ile başlayan bir konfigürasyon dosyası yolunun aslında bir boru hattı olarak okuyacağınız bir kabuk komutu olduğu konvansiyonunu kabul edebilirsiniz (ve belgeleyin ) . Bu, kullanıcınıza en aşina olduğu "önişlemci" veya "betik dili" ni kullanma seçeneği sunar.!|

(dinamik olarak hesaplanan bir yapılandırmayı kabul ediyorsanız, kullanıcıya güvenlik sorunları konusunda güvenmeniz gerekir)

Yani başlangıç ​​kodunuzda, main(örneğin) bazı --config argümanları kabul confargedip onlardan bir miktar alırsınız FILE*configf;. Bu argüman ile başlarsa !(yani eğer (confarg[0]=='!')....), configf = popen(confarg+1, "r");o boruyu kullanır ve kapatırdın pclose(configf);. Aksi takdirde configf=fopen(confarg, "r");bu dosyayı kullanır ve kapatırsınız fclose(configf);(hata kontrolünü unutmayın). Bkz borusu (7) , popen (3) , Fopen (3) . Python ile kodlanmış bir uygulama için , os.popen , vs. hakkında okuyun ...

(ayrıca yukarıdaki numarayı atlamak !foo.configiçin geçmek ./!foo.configüzere adlandırılmış bir yapılandırma dosyasını geçmek isteyen garip kullanıcı için de geçerlidir popen)

BTW, böyle bir hile sadece bir kolaylıktır (gelişmiş kullanıcının örneğin bir yapılandırma dosyası oluşturmak için bazı kabuk komut dosyası kodlamasını gerektirmesini önlemek için ). Kullanıcı herhangi bir hatayı bildirmek isterse, size oluşturulan yapılandırma dosyasını göndermelidir ...

Uygulamanızı , başlatma sırasında eklentileri kullanma ve yükleme kabiliyetine sahip olarak da tasarlayabileceğinizi , örneğin dlopen (3) kullanarak (ve bu eklenti hakkında kullanıcınıza güvenmeniz gerekir) dikkat edin. Yine, bu çok önemli bir mimari karardır (ve bu eklentiler ve uygulamanızla ilgili oldukça istikrarlı bir API ve kongre tanımlamanız ve sağlamanız gerekir ).

Python gibi bir betik dilinde kodlanmış bir uygulama için, eval veya exec ya da benzeri ilkeler için bazı program argümanlarını da kabul edebilirsiniz . Yine, güvenlik sorunları daha sonra (gelişmiş) kullanıcının endişesidir .

Yapılandırma dosyanızın metin biçimiyle ilgili olarak (oluşturulsun veya oluşturulmasın), çoğunlukla iyi bir şekilde belgelemeniz gerektiğine inanıyorum (ve belirli bir biçimin seçilmesinin o kadar önemli değil ; bazı -skipped- içindeki yorumlar). JSON'u (tercihen bazı JSON ayrıştırıcıları //eol veya /*... */... olana kadar normal olan yorumları kabul edip atlayarak ) veya YAML veya XML veya INI veya kendi işinizi kullanabilirsiniz. Bir yapılandırma dosyasını ayrıştırmak oldukça kolaydır (ve bu görevle ilgili birçok kitaplık bulacaksınız).


Programlama dillerinin Turing'in eksiksizliğinden bahsetmek için +1. Bazı ilginç çalışmalar , girdi formatının hesaplama gücünü sınırlamanın, girdi işleme katmanını güvence altına almak için anahtar olduğunu ortaya koymaktadır. Turing-complete bir programlama dili kullanmak ters yöndedir.
Matheus Moreira

2

Amonun cevabını ekleyerek , alternatifleri düşündün mü? JSON belki ihtiyaç duyduğunuzdan çok daha fazla, ancak Python dosyaları yukarıda belirtilen nedenlerden dolayı muhtemelen gelecekte size sorun yaratacak.

Ancak Python, tüm ihtiyaçlarınızı karşılayabilecek çok basit bir yapılandırma dili için bir yapılandırma çözümleyicisine sahiptir. ConfigParserModül basit bir yapılandırma dilini uygular.


1
'Benzer ... Microsoft Windows INI dosyaları' kullanmak, her ikisi de özellikle esnek bir format olmadığı gerekçesiyle kötü bir fikir gibi görünüyor ve çünkü 'benzer' belgelenmemiş uyumsuzluklar anlamına geliyor.
Pete Kirkham

1
@PeteKirkham Çok basit, belgelenmiş ve Python standart kütüphanesinin bir parçası. OP'lerin ihtiyaçları için mükemmel bir çözüm olabilir, çünkü doğrudan Python tarafından desteklenen ve JSON'dan daha basit bir şey arıyor. İhtiyaçlarının ne olduğunu daha fazla belirtmediği sürece, bu cevabın kendisine yardımcı olabileceğini düşünüyorum.
CodeMonkey

1
Esasen bunu önerecektim - Python kütüphanelerinin hangi konfigürasyon dosyalarını desteklediğini ve bunlardan birini seçtiğini görün. Ayrıca, Powershell, sınırlı Powershell dil kurgularına izin veren - zararlı kodlara karşı koruma sağlayan veri bölümleri kavramına sahiptir. Python, yapılandırma için sınırlı bir Python alt kümesini destekleyen bir kütüphaneye sahipse, en azından OP'deki fikre karşı eksilerini azaltır.
ẘpẘ

1
@PeteKirkham Etrafında başka bir problem olması daha olası. Windows, size patlayan bir sürü belgelenmemiş saçmalığa eğilim gösteriyor. Python iyi belgelenmiş ve anlaşılır olma eğilimindedir. İhtiyacınız olan tek şey basit anahtar / değer çiftleri ( belki bölümleri ile) ise, oldukça iyi bir seçim olduğunu söyledi. Bunun kullanım davalarının% 90'ını kapsadığından şüpheleniyorum. .NET'in config dosyaları canavarca XML yerine ini olsaydı, aslında config olarak kodlayan bir şemaya sahipti, hepimiz çok daha iyi olurduk.
jpmc26

1
@PeteKirkham Gerçekten değil. INI, basit kullanım durumları için ilk etapta en iyisi olmakta, herhangi bir uyumsuzluktan kaçınmanız mümkün olabilir. Ayrıca, dosyayı iki farklı dilde kullanmamanız da önemli değildir ve siz bile olsanız bile, muhtemelen herhangi bir dilde açık uygulamalar bulabilirsiniz (uyumsuzluklara sahip olmanıza izin vermemek veya en azından tam olarak ne olduğunu bilmek onlar). Kullanım durumunuz aslında bunlarla karşılaşmaya başlamanız için yeterince karmaşıksa veya mevcut bir uygulamayı bulamıyorsanız, güvenebileceğiniz, ancak bu yaygın değil, başka bir format kullanmanız gerektiğini kabul ediyorum.
jpmc26

1

Konfigürasyon dosyalarının TCL'de yazılı olduğu iyi bilinen bazı yazılımlarla uzun süre çalıştım , bu yüzden fikir yeni değil. Bu oldukça iyi çalıştı, çünkü dili bilmeyen kullanıcılar tek bir set name valueifadeyi kullanarak basit yapılandırma dosyalarını yazabiliyor / düzenleyebiliyorken , daha ileri düzey kullanıcılar ve geliştiriciler bununla karmaşık hileler çekebiliyordu.

"Yapılandırma dosyaları hata ayıklamak zor olabilir" geçerli bir endişe olduğunu sanmıyorum. Uygulamanız kullanıcıları komut dosyaları yazmaya zorlamadığı sürece, kullanıcılarınız yapılandırma dosyalarında her zaman basit atamalar kullanabilir, bu da JSON veya XML'e göre daha kolay elde etmek zorlaşır.

Config yeniden yazmak bir sorun, göründüğü kadar kötü olmasa da. İsteğe bağlı kod güncellemek mümkün değildir, ancak bir dosyadan config yüklemek, onu değiştirmek ve geri saklamaktır. Temel olarak, salt okunur olmayan bir yapılandırma dosyasında bazı komut dosyaları yazarsanız set name value, kaydedildikten sonra sadece eşdeğer bir ifadeler listesi elde edersiniz . Bunun olacağına dair iyi bir ipucu, dosyanın başında "düzenleme yapma" yorumudur.

Dikkate alınacak bir şey, config dosyalarınızın güvenilir regex tabanlı araçlarla güvenilir bir şekilde okunamayacağıdır sed, ancak anladığım kadarıyla mevcut JSON dosyalarınız için durum böyle değildir, bu yüzden kaybedecek bir şey yoktur.

Sadece config dosyalarınızı çalıştırırken uygun sanal alan tekniklerini kullandığınızdan emin olun .


1
Olması gereken bu yüzden "Yazılım" bir sayılamayan isim ise, " bazı tanınmış yazılımı."
jpmc26

1

Buradaki diğer iyi cevapların tüm geçerli noktalarının yanı sıra (vay, Turing-complete konseptinden bile bahsettiler), aslında bir Python üzerinde çalışırken bile, bir Python dosyasını yapılandırmanız olarak kullanmamanız için birkaç pratik neden var. sadece proje.

  1. Python kaynak dosyasının içindeki ayarlar salt okunur bir veri dosyası yerine teknik olarak çalıştırılabilir kaynak kodunun bir parçasıdır. Bu rotaya giderseniz, genellikle yaparsınız import config, çünkü bu tür bir "kolaylık" muhtemelen insanların Python dosyasını ilk etapta config olarak kullanmaya başlamasının en büyük nedenlerinden biriydi. Şimdi bu config.py dosyasını repounuza aktarma eğilimindesiniz, aksi takdirde son kullanıcı programınızı ilk kez çalıştırmayı denediğinde kafa karıştırıcı bir ImportError ile karşılaşır.

  2. Aslında bu config.py dosyasını repounuza aktardığınızı varsayarsak, şimdi ekip üyelerinizin muhtemelen farklı ortamlarda farklı ayarları olacak. Bir gün, bir şekilde bir üyenin yanlışlıkla yerel yapılandırma dosyasını depoya koyduğunu düşünün .

  3. Son fakat en az olmayan, projenizin yapılandırma dosyasında şifreleri olabilir. (Bu, kendi başına tartışılabilir bir uygulamadır, ancak yine de gerçekleşir.) Yapılandırma dosyanız repoda mevcutsa, kimlik bilgilerinizi genel bir repo olarak işleme koyarsınız.

Şimdi, evrensel JSON formatı gibi yalnızca veri yapılandırma dosyası kullanmak yukarıdaki 3 sorunun tümünü engelleyebilir, çünkü kullanıcıdan kendi config.json'larını bulmasını ve programınıza beslemesini makul bir şekilde isteyebilirsiniz.

Not: JSON'un birçok kısıtlaması olduğu doğru. OP tarafından belirtilen sınırlamalardan 2 tanesi bazı yaratıcılıklarla çözülebilir.

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.