لماذا يتم تعليق كود بايثون هذا عند الاستيراد/الترجمة ولكنه يعمل في الغلاف؟

StackOverflow https://stackoverflow.com/questions/1013064

سؤال

أحاول استخدام لغة بايثون لنقل ملف sftp، ويعمل الكود بشكل رائع في الغلاف التفاعلي - حتى أنه يتم لصقه مرة واحدة.

عندما أحاول استيراد الملف (فقط لتجميعه)، يتم تعليق التعليمات البرمجية دون أي استثناءات أو أخطاء واضحة.

كيف يمكنني تجميع الكود، أو هل لدى شخص ما كود عمل ينجز sftp بطريقة أخرى؟

يتم تعليق هذا الرمز مباشرةً عند عبارة ssh.connect():

""" ProblemDemo.py
    Chopped down from the paramiko demo file.

    This code works in the shell but hangs when I try to import it!
"""
from time           import sleep
import os

import paramiko


sOutputFilename     = "redacted.htm"  #-- The payload file

hostname    = "redacted.com"
####-- WARNING!  Embedded passwords!  Remove ASAP.
sUsername   = "redacted"
sPassword   = "redacted"
sTargetDir  = "redacted"

#-- Get host key, if we know one.
hostkeytype = None
hostkey     = None
host_keys   = {}
try:
    host_keys = paramiko.util.load_host_keys(os.path.expanduser('~/.ssh/known_hosts'))
except IOError:
    try:
        # try ~/ssh/ too, because windows can't have a folder named ~/.ssh/
        host_keys = paramiko.util.load_host_keys(os.path.expanduser('~/ssh/known_hosts'))
    except IOError:
        print '*** Unable to open host keys file'
        host_keys = {}

if host_keys.has_key(hostname):
    hostkeytype = host_keys[hostname].keys()[0]
    hostkey     = host_keys[hostname][hostkeytype]
    print 'Using host key of type %s' % hostkeytype


ssh     = paramiko.Transport((hostname, 22))

ssh.connect(username=sUsername, password=sPassword, hostkey=hostkey)

sftp    = paramiko.SFTPClient.from_transport(ssh)

sftp.chdir (sTargetDir)

sftp.put (sOutputFilename, sOutputFilename)

ssh.close()

هل كانت مفيدة؟

المحلول 3

وغرابة جانبا، كنت فقط باستخدام استيراد ترجمة التعليمات البرمجية. تحويل النص إلى وظيفة يبدو وكأنه تعقيد لا لزوم لها لهذا النوع من التطبيق.

وتم البحث عن وسائل بديلة لتجميع وجدت:

import py_compile
py_compile.compile("ProblemDemo.py")

ولقد تولد عن هذا الملف PYC التي تعمل على النحو المنشود. لذا فإن الدرس المستفاد هو أن استيراد ليست وسيلة قوية لتجميع مخطوطات الثعبان.

نصائح أخرى

وهذا هو في الواقع فكرة سيئة لتنفيذ هذا النوع من التعليمات البرمجية في وقت الاستيراد، على الرغم من أنني لست متأكدا من السبب في ذلك توقف - قد يكون من أن آلية استيراد يفعل شيئا غريبا التي تتفاعل بشدة مع paramiko (القضايا المتعلقة موضوع ربما؟). على أي حال، فإن الحل المعتاد هو لتنفيذ وظيفة إلى وظيفة:

def my_expensive_function(args):
    pass

if __name__ == '__main__':
    import sys
    my_expensive_functions(sys.args)

وبهذه الطريقة، فقط استيراد وحدة لن تفعل أي شيء، ولكن تشغيل البرنامج النصي سيتم تنفيذ وظيفة مع الحجج المقدمة في سطر الأوامر.

قد لا يكون هذا سببًا مباشرًا، ولكن نادرا ما تفعل ذلك من أي وقت مضى تريد تنفيذ "الوظيفة" عند الاستيراد.عادة يجب عليك تحديد أ فصل أو وظيفة التي تتصل بها بعد ذلك مثل هذا:

import mymodule
mymodule.run()

عادةً ما يجب أن يقتصر الكود "العام" الذي تقوم بتشغيله في عملية الاستيراد على عمليات الاستيراد وتعريفات المتغيرات وتعريفات الوظائف والفئة وما شابه ذلك...

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top