zoukankan      html  css  js  c++  java
  • py2exe 打包含有apscheduler(定时任务框架)后的exe运行出错

    由于py2exe打包的时候会自动根据你代码中的引用把资源给打包进来,但是凡事不是绝对的,代码中可能会有隐形的引入了其他的py文件或资源文件的时候是无法自动识别的,所以就需要手动的配置,或者做一些手动操作了,还有也可以在自己代码中先把隐形的引入用显式的引入把py文件导入比如:

    # 这个是打包apscheduler确实存在的问题,后面两个是因为后面的问题而引入的
    from apscheduler.triggers.cron import * from apscheduler.triggers.interval import IntervalTrigger from apscheduler.triggers.date import DateTrigger

    最先我遇到的问题是打包后打开exe后报错:pkg_resources.DistributionNotFound: APScheduler,这个问题搜了很久都没找到解决方案,后来硬着头皮看了下源代码,发现apscheduler/__init__.py里面代码是这样的:

    # These will be removed in APScheduler 4.0.
    release = __import__('pkg_resources').get_distribution('APScheduler').version.split('-')[0]
    version_info = tuple(int(x) if x.isdigit() else x for x in release.split('.'))
    version = __version__ = '.'.join(str(x) for x in version_info[:3])
    

      发现在打包后的发现可能是没有把APScheduler-3.3.0.dist-info资源文件打包进来导致get_distribution('APScheduler')报错了,我想这个文件好像没什么实质作用啊,然后这段代码就是为了获取apscheduler的版本号用的,所以我就把这里面的代码全部注释了,然后打包后打开exe不报这个错了,而且原来的功能也没问题,所以这应该也算是解决方法之一吧。

      但这个之后有报错:pytz.exceptions.UnknownTimeZoneError: 'Asia/Shanghai',这个我也跟了下源码,发现打包的时候又缺少文件,我那个汗。。。

      这个有两个方法:

    1. 手动复制这个zoneinfo文件到打包后的library.zip/pytz下
    2. 自己在setup.py里面写代码复制过来

      总之把文件拷贝过来就对了,具体代码下面会上,请往下看

      但是其他的资源文件,1、图片、文本类型等的非第三方库的文件  2、第三方库文件

    如果是第一种情况可以在setup中这样配置下即可:

    setup(windows=["main.py"],
          options={"py2exe": {
              'packages': ['pytz']
          }},
          # 静态资源文件路径配置
          data_files=[("img", ["img/picon.ico"]),
                      ("config", ["config/config.json"])])
    

    如果是第二种情况就要麻烦点了:

    # coding=utf-8
    __author__ = 'carlos'
    from distutils.core import setup
    
    import py2exe
    
    setup(windows=["main.py"],
          options={"py2exe": {
              'packages': ['pytz']
          }},
          # 静态资源文件路径配置
          data_files=[("img", ["img/picon.ico"]),
                      ("config", ["config/config.json"])])
    
    # 打包pytz时候缺少文件zoneinfo里的所有文件,这里是手动添加回去了
    import pytz
    import os
    import zipfile
    zipfile_path = os.path.join("dist/" 'library.zip')
    z = zipfile.ZipFile(zipfile_path, 'a')
    zoneinfo_dir = os.path.join(os.path.dirname(pytz.__file__), 'zoneinfo')
    disk_basedir = os.path.dirname(os.path.dirname(pytz.__file__))
    for absdir, directories, filenames in os.walk(zoneinfo_dir):
        assert absdir.startswith(disk_basedir), (absdir, disk_basedir)
        zip_dir = absdir[len(disk_basedir):]
        for f in filenames:
          z.write(os.path.join(absdir, f), os.path.join(zip_dir, f))
    
    z.close()
    

    或者自己手动复制这个zoneinfo文件到打包后的library.zip/pytz下。这个是打包含有pytz库的时候会有这个问题,其他如果打包遇到了此问题可以往这条路上看看,也许就是这个问题,哈哈^^!

    但是打包后还是报错:No trigger by the name "interval" was found,网上搜了下这个答案就比较多了,原因如下:

    原来的代码是:

    self.scheduler.add_job(self.DoCmd, item.get('trigger'), args=(item.get('cmd'), item.get('name')), **params)
    

    修改为:

    trigger_name = '%s%s' % (item.get('trigger').capitalize(), 'Trigger')
    trigger = eval(trigger_name)(**params)
    self.scheduler.add_job(self.DoCmd, trigger, args=(item.get('cmd'), item.get('name')))

    因为用到了IntervalTrigger, CronTrigger和DateTrigger所以上面引入了,哎呀妈呀,一个接一个问题,不得不说py2exe也不能这么智能啊,总会有这么多问题,其实我也看过其他的打包方法比如pyinstaller和cx_Freeze都有这些问题,想想看应该也是的,有些非直接的引路很难查询到,可能大牛可以吧,反正至少我没这个功底能办到呵呵...

    这里提示下初次用py2exe的人,也给自己提个醒以防自己忘记:

    py2exe打包在不同win环境下打出来的包不是可以运用于所有的win环境的,比如我再win10中打包出来的放在某些xp下就不能运行,应该是缺少一些dll文件,如果遇到这类问题试试在xp底下打包,可能可以解决这个问题。

  • 相关阅读:
    LOG4J介绍
    基于AspectJ的XML方式进行AOP开发
    tsdb import 相关
    xming + putty remote GUI
    html5 编辑
    swift container server 莫名stuck
    rsyslog trouble shooting
    文件处理 字符串处理
    list去掉重复元素
    找到字符串中最长的回文
  • 原文地址:https://www.cnblogs.com/zhaojia-dream/p/6279356.html
Copyright © 2011-2022 走看看