İçe aktarma ifadeleri her zaman bir modülün üstünde olmalı mı?


403

PEP 08 şunları belirtir:

İçe aktarmalar her zaman modül yorumlarından ve doktrinlerinden hemen sonra ve modül globalleri ve sabitlerinden önce dosyanın en üstüne yerleştirilir.

Ancak, içe aktardığım sınıf / yöntem / işlev yalnızca nadir durumlarda kullanılıyorsa, gerektiğinde içe aktarma yapmak daha verimli olur mu?

Bu değil:

class SomeClass(object):

    def not_often_called(self)
        from datetime import datetime
        self.datetime = datetime.now()

bundan daha verimli mi?

from datetime import datetime

class SomeClass(object):

    def not_often_called(self)
        self.datetime = datetime.now()

Yanıtlar:


283

Modül içe aktarma oldukça hızlı, ancak anında değil. Bunun anlamı şudur ki:

  • İthalatı modülün en üstüne koymak gayet iyi, çünkü bu sadece bir kez ödenen önemsiz bir maliyet.
  • İçe aktarmaların bir işlev içine yerleştirilmesi, o işleve yapılan çağrıların daha uzun sürmesine neden olur.

Verimliliği önemsiyorsanız, ithalatı en üste koyun. Bunları yalnızca bir profil oluşturmaya yardımcı olacak bir işlev gösteriyorsa ( performansı en iyi nerede iyileştireceğinizi görmek için profil yaptınız , değil mi?)


Tembel ithalat yapmak için gördüğüm en iyi nedenler:

  • İsteğe bağlı kütüphane desteği. Kodunuzda farklı kitaplıklar kullanan birden çok yol varsa, isteğe bağlı kitaplık yüklü değilse kırılmaz.
  • Gelen __init__.pyithal ama aslında kullanılmaz olabilecek bir eklenti, bir. Örnek olarak bzrlibtembel yükleme çerçevesini kullanan Bazaar eklentileri verilebilir .

17
John, bu tamamen teorik bir soruydu, bu yüzden profilde kodum yoktu. Geçmişte her zaman PEP'i takip ettim, ama bugün bunun doğru bir şey olup olmadığını merak etmemi sağlayan bazı kodlar yazdım. Yardımın için teşekkürler.
Adam J. Forster

43
> İçe aktarmaları bir işlevin içine yerleştirmek, o işleve yapılan çağrıların daha uzun sürmesine neden olur. Aslında, bu maliyetin sadece bir kez ödendiğini düşünüyorum. Python'un içe aktarılan bir modülü önbelleğe aldığını okudum, böylece tekrar içe aktarmanın yalnızca minimum maliyeti var.
erimiş şekil

24
@halfhourhacks Python modülü yeniden içe aktarmaz, ancak yine de modülün var olup olmadığını / sys.modules / etc'de olup olmadığını görmek için birkaç talimatı yerine getirmesi gerekir
John Millikin

24
-1. İçe aktarma işlevlerini bir işleve koymak, daha uzun sürmesine neden olmak zorunda değildir. Lütfen başka bir soruya cevabımı görün .
Ocak'ta

4
Bir kullanım örneği dairesel ithalattan kaçınmaktır (genellikle mantıklı değildir, ancak bazen uygundur). Bazen modül m1'deki A sınıfı, modül m2'deki A sınıfı başka bir A sınıfı örneğini oluşturan bir yöntemi çağırır. dairesel ithalattan kaçınılır.
Sam Svenbjorgchristiensensen

80

İmport deyimini bir işlevin içine yerleştirmek döngüsel bağımlılıkları engelleyebilir. Örneğin, X.py ve Y.py olmak üzere 2 modülünüz varsa ve her ikisinin de birbirlerini içe aktarması gerekiyorsa, sonsuz döngüye neden olan modüllerden birini içe aktardığınızda bu döngüsel bir bağımlılığa neden olur. İçe aktarma deyimini modüllerden birinde taşırsanız, işlev çağrılıncaya kadar diğer modülü içe aktarmaya çalışmaz ve bu modül zaten içe aktarılır, bu nedenle sonsuz döngü olmaz. Daha fazla bilgi için burayı okuyun - effbot.org/zone/import-confusion.htm


3
Evet ama kişi bağımlılık cehennemine girebilir.
eigenein

8
İki modülün birbirini içe aktarması gerekirse, kodla ilgili bir sorun var.
Anna

Nesneye yönelik programlama beni genellikle dairesel bağımlılıklara götürür. Hayati bir nesne sınıfı birkaç modüle alınabilir. Bu nesnenin kendi görevlerini yerine getirebilmesi için bu modüllerden birine veya daha fazlasına ulaşması gerekebilir. Bundan kaçınmanın, diğer modüllere erişmesine izin vermek için işlev argümanları aracılığıyla nesneye veri gönderme gibi yolları vardır. Ancak bunu yaparken OOP'a karşı çok sezgisel hissettiren zamanlar vardır (dış dünya onun bu işlevdeki görevi nasıl yerine getirdiğini bilmesine gerek yoktur).
Robert

4
X'in Y'ye ve Y'nin X'e ihtiyacı olduğunda, bunlar aynı fikrin iki parçasıdır (yani birlikte tanımlanmalıdır) veya eksik bir soyutlama vardır.
GLRoman

59

Tüm ithalatı modülün üstünde değil, onları kullanan fonksiyonlara koyma uygulamasını benimsedim.

Aldığım fayda, daha güvenilir bir şekilde yeniden düzenleme yeteneğidir. Bir işlevi bir modülden diğerine taşıdığımda, işlevin tüm test mirasıyla bozulmadan çalışmaya devam edeceğini biliyorum. İçe aktarımlarım modülün en üstünde yer alıyorsa, bir işlevi taşıdığımda, yeni modülün aktarımlarını tam ve minimum hale getirmek için çok zaman harcadığımı fark ettim. Yeniden düzenleme yapan bir IDE bunu ilgisiz hale getirebilir.

Başka yerlerde de belirtildiği gibi bir hız cezası var. Bunu başvurumda ölçtüm ve amaçlarım için önemsiz buldum.

Ayrıca, tüm modül bağımlılıklarını arama yapmaya başvurmadan (ör. Grep) görebilmek güzeldir. Bununla birlikte, modül bağımlılıklarını önemsememin nedeni genellikle sadece tek bir modül değil, birden fazla dosya içeren tüm sistemi yüklediğim, yeniden düzenlediğim veya taşıdığımdır. Bu durumda, sistem düzeyinde bağımlılıklara sahip olduğumdan emin olmak için yine de genel bir arama yapacağım. Bu yüzden pratikte bir sistemi anlamama yardımcı olacak küresel ithalat bulamadım.

Genellikle içe sysaktarmayı if __name__=='__main__'çekin içine koyar ve daha sonra sys.argv[1:]bir main()işleve argümanlar (beğen ) iletirim. Bu, içe aktarılmayan mainbir bağlamda kullanmama izin veriyor sys.


4
Birçok IDE, gerekli modülleri sizin için dosyanıza optimize ederek ve otomatik olarak içe aktararak kodun yeniden düzenlenmesini kolaylaştırır. Vakaların çoğunda PyCharm ve Eclipse benim için doğru kararları verdiler. Eminim emacs veya vim'de aynı davranışı elde etmenin bir yolu vardır.
brent.payne

3
Genel ad alanındaki bir if ifadesinin içindeki içe aktarma, hala genel bir içe aktarmadır. Bu, bağımsız değişkenleri yazdırır (Python 3 kullanarak): Yeni bir ad alanı oluşturmak için bir işlevi def main(): print(sys.argv); if True: import sys; main();sarmanız gerekir if __name__=='__main__'.
Darcinon

4
Bu, beni küresel kapsamdan çok işlevler içinde içe aktarmanın mükemmel bir nedeni olarak görüyor. Kimse aynı nedenden dolayı bunu yapmaktan bahsetmediğim için oldukça şaşırdım. Performans ve ayrıntı düzeyinin yanı sıra önemli bir dezavantaj var mı?
algal

@algal dezavantajı, pep kodeksini ihlal ettiğiniz için birçok piton insanının bundan nefret etmesi. Takım üyelerinizi ikna etmelisiniz. Performans cezası asgari düzeydedir. Bazen daha da hızlıdır, bkz. Stackoverflow.com/a/4789963/362951
mit

İthalatları yeniden kullandığım için ithalatı kullandığım yere yakın yerleştirmeyi çok faydalı buldum. Artık bu kadar çok zamanın üstüne ve arkasına kaydırmaya gerek yok. Ben pycharm veya kanat ide gibi IDE'ler kullanın ve aynı zamanda onların yeniden düzenleme kullanın, ancak her zaman onlara güvenmek istemiyorum. Bu alternatif içe aktarma stiliyle işlevleri başka bir modüle taşımak çok daha kolay hale gelir, sonuç olarak çok daha fazla refactor olurum.
mit

39

Çoğu zaman bu netlik açısından yararlı ve mantıklı olacaktır, ancak her zaman böyle değildir. Aşağıda modül ithalatının başka yerlerde yaşayabileceği birkaç durum örneği verilmiştir.

İlk olarak, formun birim testine sahip bir modülünüz olabilir:

if __name__ == '__main__':
    import foo
    aa = foo.xyz()         # initiate something for the test

İkinci olarak, çalışma zamanında bazı farklı modülleri koşullu olarak içe aktarma gereksiniminiz olabilir.

if [condition]:
    import foo as plugin_api
else:
    import bar as plugin_api
xx = plugin_api.Plugin()
[...]

Muhtemelen kodun diğer kısımlarına ithalat yapabileceğiniz başka durumlar da vardır.


14

İlk değişken, fonksiyon sıfır veya bir kez çağrıldığında ikincisinden daha etkilidir. Bununla birlikte, ikinci ve sonraki çağrılarla "her çağrıyı içe aktar" yaklaşımı aslında daha az verimlidir. "Tembel içe aktarma" yaparak her iki yaklaşımın en iyisini birleştiren tembel yükleme tekniği için bu bağlantıya bakın .

Ancak verimlilikten başka birini tercih etmenizin nedenleri vardır. Bir yaklaşım, bu modülün sahip olduğu bağımlılıklara ilişkin olarak kodu okuyan biri için çok daha açık hale getirmektir. Ayrıca çok farklı arıza karakteristiklerine sahiptirler - ilk olarak "datetime" modülü yoksa yükleme sırasında başarısız olur, ikincisi ise yöntem çağrılıncaya kadar başarısız olmaz.

Ek Not: IronPython'da, kod temel olarak içe aktarılırken derlendiğinden, içe aktarma CPython'dan biraz daha pahalı olabilir.



İçe aktarma hiç gerçekleşmediği için yöntem asla çağrılmazsa daha iyi performans gösterir.
Curt Hagenlocher

Doğru, ancak yöntem bir kereden fazla çağrılırsa daha kötü performans gösterir. Ve modülü hemen içe aktarmamaktan elde edeceğiniz performans avantajları çoğu durumda göz ardı edilebilir. İstisnalar, modül çok büyükse veya bu tür birçok işlev varsa olabilir.
Jason Baker

IronPython dünyasında, ilk ithalat CPython'dan çok daha pahalıdır;). Bağlantınızdaki "tembel içe aktarma" örneği, muhtemelen en iyi genel genel çözümdür.
Curt Hagenlocher

Umarım aldırmazsın, ama bunu yazında düzenledim. Bunu bilmek faydalı bir bilgi.
Jason Baker

9

Curt iyi bir noktaya işaret ediyor: ikinci versiyon daha net ve daha sonra değil, beklenmedik bir şekilde yükleme zamanında başarısız olacak.

Normalde (a) oldukça hızlı olduğu ve (b) çoğunlukla başlangıçta gerçekleştiği için, modüllerin yüklenmesi konusunda endişelenmiyorum.

Ağır modülleri beklenmedik zamanlarda yüklemeniz gerekiyorsa, bunları __import__işlevle dinamik olarak yüklemek ve istisnaları yakaladığınızdan ve makul bir şekilde kullandığınızdan emin olmak daha ImportErrormantıklıdır.


8

Modülü çok fazla yükleme verimliliğinden endişe etmem. Modül tarafından kullanılan bellek çok büyük olmayacaktır (yeterince modüler olduğu varsayılarak) ve başlangıç ​​maliyeti göz ardı edilebilir.

Çoğu durumda modülleri kaynak dosyanın en üstüne yüklemek istersiniz. Kodunuzu okuyan biri için, hangi modülden hangi fonksiyonun veya nesnenin geldiğini söylemenizi kolaylaştırır.

Bir modülü kodun başka bir yerine içe aktarmanın iyi bir nedeni, bir hata ayıklama deyiminde kullanılmasıdır.

Örneğin:

do_something_with_x(x)

Bu ile hata ayıklama olabilir:

from pprint import pprint
pprint(x)
do_something_with_x(x)

Tabii ki, modülleri kodun başka bir yerinde içe aktarmanın diğer nedeni, dinamik olarak içe aktarmanız gerektiğidir. Bunun nedeni, hemen hemen hiç seçeneğiniz olmadığıdır.

Modülü çok fazla yükleme verimliliğinden endişe etmem. Modül tarafından kullanılan bellek çok büyük olmayacaktır (yeterince modüler olduğu varsayılarak) ve başlangıç ​​maliyeti göz ardı edilebilir.


Modül başına on milisaniye başlangıç ​​maliyetinden (makinemde) bahsediyoruz. Bu, örneğin bir web uygulamasının bir kullanıcı tıklamasına yanıt verme yeteneğini etkiliyorsa, her zaman önemsiz değildir.
Evgeni Sergeev

6

Bu sadece bir programcının karar verebileceği bir ödünleşmedir.

Durum 1, datetime modülünü içe aktarmayarak (ve gerekli her başlatmayı yapmadan) gerekene kadar bellek ve başlangıç ​​zamanı tasarrufu sağlar. İçe aktarmayı 'yalnızca' çağrıldığında yapmanın 'her çağrıldığında' yapmak anlamına gelir.

Önceden yani not_often_called olduğu tarih saat ithal ederek bazı yürütme zamanı ve gecikme tasarrufu Durum 2 () o zaman daha çabuk dönecektir olan her çağrıda bir ithalat yük üstlenmeden etmeyerek da adlandırılan ve.

Verimliliğin yanı sıra, içe aktarma ifadeleri önde ise modül bağımlılıklarını görmek daha kolaydır. Onları kodda gizlemek, bir şeyin hangi modüllere bağlı olduğunu kolayca bulmanızı zorlaştırabilir.

Şahsen ben genellikle test testleri dışında kullanılmayacağını biliyorum çünkü birim testleri gibi şeyler ve her zaman yüklenmesini istemiyorum dışında PEP takip edin .


2
-1. İçe aktarmanın ana yükü yalnızca ilk kez gerçekleşir. Modüle bakmanın maliyeti, sys.modulesküresel bir ad yerine yalnızca yerel bir ad aramak zorunda kalmadan yapılan tasarruflarla kolayca dengelenebilir.
aaronasterling

6

İşte tüm ithalatın en üstte olduğu bir örnek (bunu yapmak için ihtiyacım olan tek zaman). Hem Un * x hem de Windows üzerinde bir alt süreci sonlandırmak istiyorum.

import os
# ...
try:
    kill = os.kill  # will raise AttributeError on Windows
    from signal import SIGTERM
    def terminate(process):
        kill(process.pid, SIGTERM)
except (AttributeError, ImportError):
    try:
        from win32api import TerminateProcess  # use win32api if available
        def terminate(process):
            TerminateProcess(int(process._handle), -1)
    except ImportError:
        def terminate(process):
            raise NotImplementedError  # define a dummy function

(İncelemede: John Millikin ne dedi.)


6

Bu, diğer birçok optimizasyon gibidir - hız için okunabilirliği feda edersiniz. John'un belirttiği gibi, profil oluşturma ödevinizi yaptıysanız ve bunu yeterince faydalı bir değişiklik olarak bulduysanız ve ekstra hıza ihtiyacınız varsa, o zaman devam edin. Diğer tüm ithalatları not etmek muhtemelen iyi olur:

from foo import bar
from baz import qux
# Note: datetime is imported in SomeClass below

4

Modül başlatma yalnızca bir kez gerçekleşir - ilk içe aktarmada. Söz konusu modül standart kütüphaneden geliyorsa, muhtemelen programınızdaki diğer modüllerden de içe aktaracaksınız. Tarih-saat kadar yaygın olan bir modül için, diğer standart kütüphanelerin de bir bağımlılığı olması muhtemeldir. Modül başlatma zaten gerçekleştiğinden, içe aktarma ifadesinin maliyeti çok az olurdu. Bu noktada tek yaptığı mevcut modül nesnesini yerel kapsama bağlamaktır.

Bu bilgiyi okunabilirlik argümanı ile birleştirin ve modül kapsamındaki ithalat ifadesine sahip olmanın en iyisi olduğunu söyleyebilirim.


4

Moe'nun cevabını ve orijinal soruyu tamamlamak için:

Dairesel bağımlılıklarla uğraşmak zorunda kaldığımızda bazı “numaralar” yapabiliriz. Biz modülleri ile çalışıyoruz varsayarsak a.pyve b.pyiçerdiğini x()b y()sırasıyla. Sonra:

  1. from importsModülün alt kısmındaki birini taşıyabiliriz .
  2. from importsİçe aktarmayı gerektiren işlev veya yöntemin içinden birini taşıyabiliriz (birkaç yerden kullanabileceğiniz için bu her zaman mümkün değildir).
  3. İkisinden birini, from importsaşağıdakine benzeyen bir içe aktarma olarak değiştirebiliriz :import a

Sonuç olarak. Dairesel bağımlılıklar ile uğraşmıyorsanız ve bunlardan kaçınmak için bir tür hile yapıyorsanız, bu sorunun diğer cevaplarında zaten açıklanmış nedenlerden dolayı tüm ithalatlarınızı en üste koymak daha iyidir. Ve lütfen, bu "hileler" yaparken bir yorum içerir, her zaman açığız! :)


4

Halihazırda verilen mükemmel cevaplara ek olarak, ithalatın yerleştirilmesinin sadece bir stil meselesi olmadığını belirtmek gerekir. Bazen bir modülün ilk olarak içe aktarılması veya başlatılması gereken örtülü bağımlılıkları vardır ve üst düzey içe aktarma, gerekli yürütme sırasının ihlaline yol açabilir.

Bu sorun genellikle Apache Spark'ın Pyspark paketlerini veya modüllerini içe aktarmadan önce SparkContext'i başlatmanız gereken Python API'sinde ortaya çıkar. Pyspark ithalatını SparkContext'in kullanılabilir olduğu garanti edilen bir yere yerleştirmek en iyisidir.


4

Ne olacağını çok iyi açıklamalar olmasına rağmen, zaten yayınlanan tekrarlanan yük kontrolleri için gerçek maliyet numaraları görmek için sürpriz oldu.

En üste aktarırsanız, ne olursa olsun yük vuruşunu alırsınız. Bu oldukça küçüktür, ancak genellikle milisaniyede değil, nanosaniyede değil.

Eğer bir işlev (ler) içinde içe aktarırsanız, o zaman sadece yükleme için isabet almak durumunda ve ne zaman bu işlevlerden biri ilk olarak adlandırılır. Birçoğunun işaret ettiği gibi, bu hiç olmazsa, yükleme süresinden tasarruf edersiniz. Fonksiyon (lar) çok denilen olsun Ama eğer bir (o kontrol etmek için çok daha küçük hit olsa tekrarlanan almak gelmiştir ; aslında üzere yeniden yükleme yüklenmiş). Öte yandan, @aaronasterling'in işaret ettiği gibi, bir işlev içine içe aktarma, işlevin adı daha sonra tanımlamak için biraz daha hızlı yerel değişken aramaları kullanmasına izin verdiği için biraz tasarruf edersiniz ( http://stackoverflow.com/questions/477096/python- içe aktarma kodlama stili / 4789963 # 4789963 ).

İşte bir fonksiyonun içinden birkaç şeyi içe aktaran basit bir testin sonuçları. Bildirilen süreler (2.3 GHz Intel Core i7'de Python 2.7.14'te) aşağıda gösterilmektedir (nedenini bilmiyorum, ancak daha sonradan daha fazla çağrı alan 2. çağrı tutarlı görünüyor).

 0 foo:   14429.0924 µs
 1 foo:      63.8962 µs
 2 foo:      10.0136 µs
 3 foo:       7.1526 µs
 4 foo:       7.8678 µs
 0 bar:       9.0599 µs
 1 bar:       6.9141 µs
 2 bar:       7.1526 µs
 3 bar:       7.8678 µs
 4 bar:       7.1526 µs

Kod:

from __future__ import print_function
from time import time

def foo():
    import collections
    import re
    import string
    import math
    import subprocess
    return

def bar():
    import collections
    import re
    import string
    import math
    import subprocess
    return

t0 = time()
for i in xrange(5):
    foo()
    t1 = time()
    print("    %2d foo: %12.4f \xC2\xB5s" % (i, (t1-t0)*1E6))
    t0 = t1
for i in xrange(5):
    bar()
    t1 = time()
    print("    %2d bar: %12.4f \xC2\xB5s" % (i, (t1-t0)*1E6))
    t0 = t1

Çalışma zamanındaki değişiklikler muhtemelen yüke yanıt olarak CPU frekansı ölçeklendirmesinden kaynaklanmaktadır. CPU saat hızının artmasını sağlamak için bir saniye yoğun çalışma ile hız testlerine başlamak daha iyidir.
Han-Kwang Nienhuys

3

Tam bir cevap vermek istemiyorum, çünkü diğerleri bunu çok iyi yaptı. İşlevlerin içindeki modülleri içe aktarmak için özellikle yararlı bulduğumda sadece bir kullanım durumundan bahsetmek istiyorum. Uygulamam eklenti olarak belirli bir yerde saklanan python paketleri ve modülleri kullanıyor. Uygulama başlatılırken, uygulama konumdaki tüm modülleri dolaşır ve içe aktarır, daha sonra modüllerin içine bakar ve eklentiler için bazı montaj noktaları bulursa (benim durumumda benzersiz bir temel sınıfın bir alt sınıfıdır) ID) kaydeder. Eklenti sayısı büyüktür (şimdi düzinelerce, ancak belki de yüzlerce) ve her biri oldukça nadiren kullanılmaktadır. Eklenti modüllerimin üstünde üçüncü taraf kitaplıkların içe aktarılması, uygulamanın başlatılması sırasında biraz cezalandırıldı. Özellikle bazı üçüncü taraf kütüphaneleri ithal etmek için ağırdır (örneğin, plotly'nin içe aktarılması bile internete bağlanmaya ve başlangıç ​​için yaklaşık bir saniye ekleyen bir şey indirmeye çalışır). Eklentilerdeki içe aktarmaları optimize ederek (yalnızca kullanıldıkları işlevlerde çağırarak), başlatmayı 10 saniyeden 2 saniyeye çekmeyi başardım. Bu kullanıcılarım için büyük bir fark.

Cevabım hayır, ithalatı her zaman modüllerinizin üstüne koymayın.


3

Şimdiye kadar, paralel işlemden bahsettiğimiz tek bir cevabın olmaması, diziselleştirilmiş fonksiyon kodu, örneğin ipyparallel durumunda olduğu gibi, diğer çekirdeklere itilen şey olduğunda, ithalatın işlevde olması GEREKLİ olabilir.


1

Bir işlevin içindeki değişkenleri / yerel kapsamı içe aktararak bir performans kazancı olabilir. Bu, içe aktarılan şeyin işlev içinde kullanımına bağlıdır. Birçok kez döngü yapıyorsanız ve bir modül global nesnesine erişiyorsanız, yerel olarak içe aktarmak yardımcı olabilir.

test.py

X=10
Y=11
Z=12
def add(i):
  i = i + 10

runlocal.py

from test import add, X, Y, Z

    def callme():
      x=X
      y=Y
      z=Z
      ladd=add 
      for i  in range(100000000):
        ladd(i)
        x+y+z

    callme()

run.py

from test import add, X, Y, Z

def callme():
  for i in range(100000000):
    add(i)
    X+Y+Z

callme()

Linux'ta bir zaman küçük bir kazanç gösterir

/usr/bin/time -f "\t%E real,\t%U user,\t%S sys" python run.py 
    0:17.80 real,   17.77 user, 0.01 sys
/tmp/test$ /usr/bin/time -f "\t%E real,\t%U user,\t%S sys" python runlocal.py 
    0:14.23 real,   14.22 user, 0.01 sys

gerçek duvar saati. kullanıcı programda zamanı. sys, sistem çağrılarının zamanıdır.

https://docs.python.org/3.5/reference/executionmodel.html#resolution-of-names


1

Okunabilirlik

Başlangıç ​​performansına ek olarak, importifadeleri yerelleştirmek için okunabilirlik argümanı vardır . Örneğin, geçerli ilk python projemde 1283 ile 1296 arasındaki python satır numaralarını al:

listdata.append(['tk font version', font_version])
listdata.append(['Gtk version', str(Gtk.get_major_version())+"."+
                 str(Gtk.get_minor_version())+"."+
                 str(Gtk.get_micro_version())])

import xml.etree.ElementTree as ET

xmltree = ET.parse('/usr/share/gnome/gnome-version.xml')
xmlroot = xmltree.getroot()
result = []
for child in xmlroot:
    result.append(child.text)
listdata.append(['Gnome version', result[0]+"."+result[1]+"."+
                 result[2]+" "+result[3]])

İfade importdosyanın üst kısmında olsaydı, uzun bir yol kaydırmam veya Homene olduğunu bulmak için , tuşuna basmam gerekirdi ET. Sonra kodu okumaya devam etmek için 1283 satırına geri dönmek zorunda kalacak.

Gerçekten de, importifade çoğu kişinin yerleştireceği gibi işlevin (veya sınıfın) üstünde olsa bile , yukarı ve aşağı sayfalama gerekir.

Gnome sürüm numarasının görüntülenmesi nadiren yapılır, böylece importdosyanın üst kısmında gereksiz başlatma gecikmesi olur.


0

@John Millikin ve @VK tarafından belirtilenlere çok benzeyen bir kullanım alanımdan bahsetmek istiyorum:

İsteğe Bağlı İthalat

Jupyter Notebook ile veri analizi yapıyorum ve tüm analizler için şablon olarak aynı IPython not defterini kullanıyorum. Bazı durumlarda, bazı hızlı model çalışmaları yapmak için Tensorflow'u içe aktarmam gerekiyor, ancak bazen tensorflow'un ayarlanmadığı / içe aktarılmasının yavaş olduğu yerlerde çalışıyorum. Bu durumlarda, Tensorflow'a bağlı işlemlerimi yardımcı bir işlevde kapsül haline getirir, tensorflow'u bu işlevin içine alır ve bir düğmeye bağlarım.

Bu şekilde, içe aktarmayı beklemek zorunda kalmadan veya başarısız olduğunda hücrelerin geri kalanını sürdürmek zorunda kalmadan "yeniden başlat ve çalıştır" ı yapabilirim.


0

Bu büyüleyici bir tartışma. Diğerleri gibi ben de bu konuyu hiç düşünmemiştim. Django ORM'yi kütüphanelerimden birinde kullanmak istediği için işlevlerde ithalat yapmak zorunda kaldım. django.setup()Model sınıflarımı içe aktarmadan önce aramak zorunda kaldım ve bu dosyanın en üstünde olduğu için IoC enjektör yapısı nedeniyle tamamen Django olmayan kütüphane koduna sürükleniyordu.

Ben biraz etrafında saldırıya uğradı ve django.setup()singleton yapıcı ve ilgili ithalat her sınıf yönteminin üstüne koyarak sona erdi . Şimdi bu iyi çalıştı ama beni tedirgin etti çünkü ithalat en üstte değildi ve aynı zamanda ithalatın fazladan zamanından endişe duymaya başladım. Sonra buraya geldim ve herkesin bu konudaki ilgisini büyük bir ilgi ile okudum.

Ben uzun bir C ++ arka plan var ve şimdi Python / Cython kullanın. Bunu benim üstlenmemin nedeni, size profilli bir darboğaz neden olmadıkça, ithalatı neden işleve dahil etmemek. Bu sadece değişkenlere ihtiyaç duymadan hemen önce yer bildirmek gibidir. Sorun üstte tüm ithalatı ile binlerce satır kod var! Bu yüzden bundan sonra yapacağım ve geçirdiğimde ve zamanım olduğunda garip dosyayı burada ve orada değiştireceğim.

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.