'ආනයන මොඩියුලය' එදිරිව. '


159

මම සෑම විටම මෙම ක්‍රමය භාවිතා කර ඇත:

from sys import argv

සහ argvargv සමඟ භාවිතා කරන්න . නමුත් මෙය භාවිතා කිරීමේ සම්මුතියක් තිබේ:

import sys

සහ argv භාවිතා කිරීම sys.argv

දෙවන ක්‍රමය මඟින් කේතය ස්වයං ලේඛනගත කර ඇති අතර මම (සැබවින්ම) එය පිළිපදින්නෙමි. නමුත් මම පළමු ක්‍රමයට වැඩි කැමැත්තක් දැක්වීමට හේතුව එය වේගවත් වන්නේ අප ආනයනය කරන්නේ සමස්ත මොඩියුලය ආනයනය කරනවාට වඩා අවශ්‍ය ශ්‍රිතය පමණක් වන නිසාය (පයිතන් ආනයනය කිරීමට කාලය නාස්ති කරන වඩා නිෂ් less ල කාර්යයන් එහි අඩංගු වේ). මට අවශ්‍ය වන්නේ argv පමණක් වන අතර sys වෙතින් ලැබෙන අනෙකුත් සියලුම කාර්යයන් මට නිෂ් less ල ය.

ඉතින් මගේ ප්‍රශ්න. පළමු ක්‍රමය මඟින් ස්ක්‍රිප්ට් වේගවත් කරයිද? වඩාත්ම කැමති ක්‍රමය කුමක්ද? මන්ද?



Answers:


189

මෙම මොඩියුලය ආනයනය නාස්ති කරන්නේ නැහැ කිසිම දෙයක් , මොඩියුලය සැමවිටම සම්පුර්ණයෙන්ම ආනයනය කරනු ලැබේ ( sys.modulesසිතියම් ගත කිරීම සඳහා), එබැවින් ඔබ තෙතමනය භාවිතා කරයි import sysහෝ from sys import argvකිසිදු ගැටළුවක් නොකරයි.

ප්‍රකාශ දෙක අතර ඇති එකම වෙනස නම් බැඳී ඇති නමයි; මොඩියුලයට import sysනම බන්ධනය කරයි sys(එසේ sys-> sys.modules['sys']), from sys import argvවෙනත් නමක් බන්ධනය කරන අතර argv, මොඩියුලයේ ඇතුළත ඇති ගුණාංගයට කෙළින්ම යොමු කරයි (එබැවින් argv-> sys.modules['sys'].argv). sysඔබ මොඩියුලයෙන් වෙනත් දෙයක් භාවිතා කළත් නැතත්, මොඩියුලයේ ඉතිරි කොටස තවමත් පවතී.

ප්රවේශයන් දෙක අතර කාර්ය සාධන වෙනසක් ද නොමැත. ඔව්, sys.argvකරුණු දෙකක් සොයා බැලිය යුතුය; එය sysඔබගේ ගෝලීය නාම අවකාශයේ සොයා බැලිය යුතුය (මොඩියුලය සොයා ගනී), පසුව ගුණාංගය සොයා බලන්න argv. ඔව්, from sys import argvඔබට දැනටමත් ගුණාංගය පිළිබඳ සෘජු සඳහනක් ඇති බැවින්, භාවිතා කිරීමෙන් ඔබට ගුණාංග බැලීම මඟ හැරිය හැක. නමුත් importප්‍රකාශය තවමත් එම කාර්යය කළ යුතුව ඇත, ආනයනය කිරීමේදී එය එකම ගුණාංගයක් ලෙස පෙනේ, ඔබට භාවිතා කිරීමට අවශ්‍ය වන්නේ argv එක් වරක් පමණි . ඔබට argvලූපයක් තුළ දහස් වාරයක් භාවිතා කිරීමට සිදුවුවහොත් එය යම් වෙනසක් කළ හැකිය, නමුත් මෙම විශේෂිත අවස්ථාවෙහිදී එය සැබවින්ම සිදු නොවේ.

එක හෝ අනෙක අතර තේරීම ඒ වෙනුවට කේතීකරණ විලාසය මත පදනම් විය යුතුය .

දී විශාල මොඩියුලය, මම භාවිතා කරනවා import sys; කේත ප්‍රලේඛනය වැදගත් වන sys.argvඅතර විශාල මොඩියුලයක කොතැනක හෝ භාවිතා කිරීමෙන් ඔබ යොමු කරන දෙය වෙන argvකවරදාටත් වඩා පැහැදිලි වේ.

ඔබ භාවිතා කරන එකම තැන නම්, argvයනු විශාල '__main__'කැඳවීමට වාරණ main()සියලු මාර්ගයෙන්, ක්රියාව භාවිත from sys import argvඔයා ඒ ගැන සතුටු වෙනවා නම්:

if __name__ == '__main__':
    from sys import argv
    main(argv)

මම තවමත් import sysඑහිම භාවිතා කරමි. සෑම දෙයක්ම එක හා සමානයි (ඒවා හරියටම කාර්ය සාධනය සහ එය ලිවීමට භාවිතා කරන චරිත ගණන අනුව), එය මට ඇසට පහසුය.

ඔබ වෙනත් දෙයක් මුළුමනින්ම ආනයනය කරන්නේ නම් , සමහර විට කාර්ය සාධනය ක්‍රියාත්මක වේ. නමුත් ඔබ මොඩියුලයක නිශ්චිත නමක් බොහෝ වාරයක් භාවිතා කරන්නේ නම් පමණක්, උදාහරණයක් ලෙස විවේචනාත්මක පුඩුවක් තුළ. නමුත් පසුව දේශීය නමක් සෑදීම (ශ්‍රිතයක් තුළ) තවමත් වේගවත් වනු ඇත:

 import somemodule

 def somefunction():
      localname = somemodule.somefunctionorother
      while test:
          # huge, critical loop
          foo = localname(bar)

1
ඉහළ මට්ටමේ පැකේජයේ ඇති එක් උප පැකේජයක / මොඩියුලයක ගුණාංගයක් නිරාවරණය කරන උප පැකේජ හෝ මොඩියුල සහිත පැකේජයක් ඔබ සතුව ඇති තත්වය ද තිබේ. භාවිතා from...importකිරීම ඔබට package.attributeවඩා කිරීමට ඉඩ දෙයි, ඔබට package.subpackage_or_module.attributeපැකේජය තුළ තාර්කික හෝ සංකල්පීය කණ්ඩායම් තිබේ නම් එය ප්‍රයෝජනවත් විය හැකි නමුත් ඔබේ පැකේජයේ පරිශීලකයින්ට දේවල් ටිකක් පහසු කිරීමට අවශ්‍ය නම්. ( numpyමේ වගේ දෙයක් කරයි, මම විශ්වාස කරමි.)
ජාබ්

ජැන්ගෝ හි ඔබට ටොන් ගණනක් ඇති අතර from django.core.management.base import BaseCommandවඩා හොඳ දේවල් ඇති අතර වෙනත් ඕනෑම දෙයක් (විශේෂයෙන් import django) කියවිය නොහැකි කේතයකට තුඩු දෙනු ඇත. එබැවින් මම මෙම පිළිතුරට කැමති අතර, සම්මේලනය හිස් ආනයනය උල්ලං to නය කිරීම සඳහා පුස්තකාල කිහිපයක් (සහ විශේෂයෙන් සමහර රාමු) ඇති බව මම සිතමි. සෑම විටම මෙන්, දී ඇති තත්වයක හොඳම දේ පිළිබඳ ඔබේ විනිශ්චය භාවිතා කරන්න. නමුත් පැහැදිලි පැත්තෙන් වැරදියි (වෙනත් වචන වලින් කිවහොත් මම බොහෝ දුරට එකඟ වෙමි).
නියුරෝනෙට්

1
AB ජාබ්: ඔබට තවමත් import ... asවෙනත් නමකට පැකේජය සොයා ගැනීමට භාවිතා කළ හැකිය : import package.subpackage_or_module as shortname. from parent import subඅවශ්‍යයෙන්ම එකම දේ කරයි.
මාර්ටිජ් පීටර්ස්

so wether you use import sys or from sys import argv makes no oddsIDLE හි මෙය එසේ නොවන බව පෙනේ. හුදෙක් මොඩියුලය ආනයනය එහි කටයුතු ආනයනය කරන්නේ නැහැ මම <මොඩියුලය> පමණක් භාවිතයට අවශ්ය නොවන ෂෙල් එය ඇමතිය හැකි <කාර්යය> නම.
Suncatcher

Un සන්කැචර්: මගේ පිළිතුර සම්පූර්ණයෙන් කියවන්න. ඔබ උපුටා දක්වන වාක්‍යය ආනයනය කරන්නේ කොපමණ ප්‍රමාණයක් ගැනද, කුමන නමක් බැඳී ඇත්ද යන්න ගැන ය. එය පිළිතුරේ වෙනත් තැනක ආවරණය කර ඇත.
මාර්ටිජන් පීටර්ස්

48

භාවිතා import moduleකිරීමට වඩා හේතු දෙකක් තිබේ from module import function.

පළමුවැන්න නම් අවකාශයයි. ගෝලීය නාම අවකාශයට ශ්‍රිතයක් ආයාත කිරීම නාම ගැටුම් අවදානමට ලක් කරයි.

දෙවැන්න සම්මත මොඩියුලයන්ට අදාළ නොවේ, නමුත් විශේෂයෙන් මොඩියුලයන් ඔබටම වැදගත් වේ, විශේෂයෙන් සංවර්ධනය අතරතුර. එය reload()මොඩියුලයකට ඇති විකල්පයයි . මෙය සලකා බලන්න:

from module import func
...
reload(module)
# func still points to the old code

අනිත් අතට

import module
...
reload(module)
# module.func points to the new code

වේගය සම්බන්ධයෙන් ...

අප ආනයනය කරන්නේ සම්පූර්ණ මොඩියුලය ආනයනය කරනවාට වඩා අවශ්‍ය ශ්‍රිතය පමණි (පයිතන් ආනයනය කිරීමට කාලය නාස්ති කරන වැඩකට නැති කාර්යයන් එහි අඩංගු වේ)

ඔබ මොඩියුලයක් ආනයනය කළත්, මොඩියුලයකින් ශ්‍රිතයක් ආනයනය කළත්, පයිතන් මුළු මොඩියුලයම විග්‍රහ කරයි. මොඩියුලය ආනයනය කරන ආකාරය කෙසේ හෝ වේ. “ශ්‍රිතයක් ආයාත කිරීම” යනු ශ්‍රිතය නමකට බැඳීමට වඩා වැඩි දෙයක් නොවේ. ඇත්ත වශයෙන්ම import moduleපරිවර්තකයාට වඩා අඩු කාර්යයකි from module import func.


6
රීලෝඩ් () යනු පයිතන් 2 හි ඉදිකරන ලද්දකි; පයිතන් 3 සඳහා එය තවදුරටත් එසේ නොවේ.
ඇන්ඩ්‍රේ

චක්‍රලේඛ ආනයන පරායත්තතාවයන් සමඟ ද ඇඟවුම් කළ හැකි යැයි මම සිතුවෙමි.
ADP

19

from importකියවීමේ හැකියාව වැඩි දියුණු කරන සෑම විටම මම s භාවිතා කරමි . උදාහරණයක් ලෙස, මම කැමතියි (අර්ධ සළකුණු යනු මෙහි ඉඩ ඉතිරි කර ගැනීම සඳහා පමණි):

from collections import defaultdict
from foomodule import FooBar, FooBaz
from twisted.internet.protocol import Factory
defaultdict(); FooBar(); FooBaz(); Factory()

වෙනුවට:

import collections
import foomodule
import twisted.internet.protocol
collections.defaultdict(); foomodule.FooBar(); foomodule.FooBaz()
twisted.internet.protocol.Factory()

දෙවැන්න මට අතිරික්ත තොරතුරු අඩංගු බැවින් එය කියවීමට (සහ ලිවීමට) අපහසුය. එසේම, මා භාවිතා කරන මොඩියුලයක කොටස් මොනවාදැයි කල්තියා දැන ගැනීම ප්‍රයෝජනවත් වේ.

මම importමොඩියුලයකින් කෙටි නම් ගොඩක් භාවිතා කරන්නේ නම් මම සාමාන්‍ය s වලට කැමතියි :

import sys
sys.argv; sys.stderr; sys.exit()

නැතහොත් නමක් එහි නාම අවකාශයෙන් පිටත තේරුමක් නැති තරමට සාමාන්‍ය නම්:

import json
json.loads(foo)

from json import loads
loads(foo)  # potentially confusing

මෙය මගේ ප්‍රියතම පිළිතුරයි. 'ව්‍යංගයට වඩා පැහැදිලිය' සමහර විට කියවීමේ හැකියාව, සරල බව සහ ඩ්‍රයි සමඟ ගැටෙයි. විශේෂයෙන් ජැන්ගෝ වැනි රාමුවක් භාවිතා කරන විට.
නියුරෝනෙට්

19

මගේ මතය අනුව නිතිපතා භාවිතා කිරීම importකියවීමේ හැකියාව වැඩි දියුණු කරයි. පයිතන් කේතය සමාලෝචනය කරන විට, ලබා දී ඇති ශ්‍රිතය හෝ පන්තිය භාවිතා වන්නේ කොතැනින් දැයි බැලීමට මා කැමතිය. එම තොරතුරු ලබා ගැනීම සඳහා මොඩියුලයේ ඉහළට අනුචලනය කිරීමෙන් එය මාව ගලවා ගනී.

දිගු මොඩියුලයේ නම් සඳහා මම asයතුරු පදය භාවිතා කර ඒවාට කෙටි අන්වර්ථ නාමයන් ලබා දෙමි :

import collections as col
import foomodule as foo
import twisted.internet.protocol as twip

my_dict = col.defaultdict()
foo.FooBar()
twip_fac = twip.Factory()

ව්‍යතිරේකයක් ලෙස මම මොඩියුලය from module import somethingසමඟ ගනුදෙනු කරන විට සෑම විටම අංකනය භාවිතා කරමි __future__. පයිතන් 2 හි පෙරනිමියෙන් සියලුම නූල් යුනිකෝඩ් වීමට අවශ්‍ය විට ඔබට එය වෙනත් ආකාරයකින් කළ නොහැක.

from __future__ import unicode_literals
from __future__ import print_function

ආමෙන්! "import as" යනු ජයග්‍රාහී සංයෝජනයකි :-)
paj28

4

නමුත් import sysසහ from sys import agrvසමස්ත දෙකම ආනයන sysමොඩියුලය, අග භාවිතා බන්ධන නම් එසේ පමණක් argvමොඩියුලය කේත විවේක ලබාගත හැකි ය.

සමහර පුද්ගලයින් සඳහා මෙය වඩාත් කැමති ශෛලිය වනු ඇත, මන්ද එය ඔබ පැහැදිලිව ප්‍රකාශ කළ ශ්‍රිතයට පමණක් ප්‍රවේශ විය හැකි බැවිනි.

කෙසේ වෙතත් එය විභව නාම ගැටුම් හඳුන්වා දෙයි. ඔබට තවත් මොඩියුලයක් නම් කර ඇත්නම් කුමක් කළ argvයුතුද? ඔබට පැහැදිලිවම ආනයනය කළ හැකි අතර, නැවත ආනයනය කළ හැකි අතර from sys import argv as sys_argv, සම්මුතියක් මගින් පැහැදිලි ආනයනය සපුරාලන අතර නම අවකාශයේ .ට්ටන ලබා දීමට ඇති ඉඩකඩ අඩුය.


2
ඉතින් ඊට if sys_argv:වඩා හොඳ if sys.argv:කොහොමද? දෙවන ප්‍රකාශයේ තේරුම කුමක්දැයි මම දනිමි, විකාර ආනයනයට පිටුපසට නොගෙන පළමු පෝරමයේ තේරුම කුමක්දැයි මා දන්නේ නැත.
msw

1

මම මෑතකදී මෙම ප්‍රශ්නය මගෙන්ම ඇසුවෙමි. මම විවිධ ක්‍රම කාලානුරූපව තැබුවෙමි.

පුස්තකාලය ඉල්ලයි

def r():
    import requests
    return 'hello'
timeit r() # output: 1000000 loops, best of 3: 1.55 µs per loop

def rg():
    from requests import get
    return 'hello'
timeit rg() # output: 100000 loops, best of 3: 2.53 µs per loop

ලස්සන පුස්තකාලය

def bs():
    import bs4
    return 'hello' 
timeit bs() # output: 1000000 loops, best of 3: 1.53 µs per loop

def be():
    from bs4 import BeautifulSoup
    return 'hello'
timeit be() # output: 100000 loops, best of 3: 2.59 µs per loop

json පුස්තකාලය

def js():
    import json
    return 'hello'
timeit js() # output: 1000000 loops, best of 3: 1.53 µs per loop

def jl():
    from json import loads
    return 'hello'
timeit jl() # output: 100000 loops, best of 3: 2.56 µs per loop

sys පුස්තකාලය

def s():
    import sys
    return 'hello'
timeit s() # output: 1000000 loops, best of 3: 1.55 µs per loop

def ar():
    from sys import argv
    return 'hello'
timeit ar() # output: 100000 loops, best of 3: 2.87 µs per loop

මට ඒක නිකං පවතී කාර්ය සාධන සුළු වශයෙන් වෙනස්.


ඔබ එකතු කිරීමේ ගුණාංගයක් එකතු කරමින් සිටී. සන්සන්දනය කිරීම import moduleසමග from module import nameනිවැරදි ලෙස, එක් කිරීමට නාමය බැලීම බව import moduleනඩුව. උදා: රේඛාව එකතු sys.argvකිරීමට arආදී පරීක්ෂණ, සිදු කළ කාර්යය නිසා එහි තවමත්, මෙම වෙනස් වනු ඇත තරමක් වෙනස් bytecode ජනනය කරනු ඇති අතර විවිධ codepaths ක්රියාත්මක වන ලෙස, විවිධ.
මාර්ටිජන් පීටර්ස්

2
මගේ පිළිතුරේ එම වෙනස මා කෙලින්ම ආමන්ත්‍රණය කරන බව සලකන්න; එදිරිව එදිරිව එදිරිව ලූපයක් import sysභාවිතා කිරීම අතර වෙනසක් ඇත . නමුත් ඔබ එසේ කරන්නේ නැහැ. ඔබගේ මොඩියුලයේ ගෝලීය මට්ටමින් ඔබ එක් වරක් පමණක් කරන දේවල් සඳහා , ඔබ සැබවින්ම කියවීමේ හැකියාව සඳහා ප්‍රශස්තිකරණය කළ යුතු අතර වේලාවන්හි අන්වීක්ෂීය වෙනස්කම් නොවේ. sys.argvfrom sys import argvargv
මාර්ටිජන් පීටර්ස්

1
අහ්හ්! මම හිතුවේ මම යම් දෙයකට යොමු වෙලා කියලා! :) මම ඔබේ පිළිතුර මග හැරියෙමි. පේන විදියට මම තුවක්කුව ඒකට ගැහුවා. නිහතමානී වීම සතුටක්.
tmthyjames

-1

ප්‍රකාශිත කේත කොටස් දෙස බැලීම, සම්පූර්ණ මොඩියුල ආනයනය කිරීම සහ යොමු කිරීම module.functionඅවම වශයෙන් සම්මත මොඩියුල සඳහා ප්‍රමිතියකි. එක් ව්යතිරේකයක් ලෙස පෙනේdatetime

from datetime import datetime, timedelta

ඒ නිසා ඔබට datetime.now()වඩා කියන්න පුළුවන් datetime.datetime.now().

ඔබ කාර්ය සාධනය ගැන සැලකිලිමත් නම්, ඔබට සැමවිටම පැවසිය හැකිය (උදාහරණයක් ලෙස)

argv = sys.argv

මොඩියුලය සෙවීම දැනටමත් සිදු කර ඇති බැවින් ඔබේ කාර්ය සාධන විවේචනාත්මක කේතය කරන්න. කෙසේ වෙතත් මෙය ශ්‍රිත / ක්‍රම සමඟ ක්‍රියා කළද, බොහෝ IDE හි ව්‍යාකූලත්වයට පත්වන අතර (උදාහරණයක් ලෙස) එය විචල්‍යයකට පවරා ඇති විට ශ්‍රිතය සඳහා ප්‍රභව සම්බන්ධකයක් / අත්සනක් නොපෙන්වයි.


-2

මට අවශ්‍ය වන්නේ ඔබ එවැනි දෙයක් කරන්නේ නම් එය එකතු කිරීමයි

from math import sin

(හෝ වෙනත් හෝ සාදන ලද පුස්තකාලයක් sysහෝ වැනි posix), පසුව sinඔබේ මොඩියුලය සඳහා වන ප්‍රලේඛනයට ඇතුළත් වේ (එනම් ඔබ එසේ කරන විට >>> help(mymodule)හෝ $ pydoc3 mymodule. මෙය වළක්වා ගැනීම සඳහා, ආනයනය කරන්න:

import math
from math import sin as _sin

PS: සාදන ලද පුස්තකාලයක් යනු සී කේතයෙන් සම්පාදනය කර පයිතන් සමඟ ඇතුළත් කර ඇති පුස්තකාලයකි. argparse, osසහ ioඒවා සාදන ලද පැකේජ නොවේ

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.