导入的模块在运行功能时变为“无” [英] Imported modules become None when running a function

查看:108
本文介绍了导入的模块在运行功能时变为“无”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:在这篇文章的底部有一些更多的调试信息,这揭示了python状态非常棘手的一些。



我有一个模块,其中导入了django User对象。



导入工作正常,代码加载。但是,当您调用该模块中使用User对象的函数时,会出现错误,表示User是NoneType。



还有一些其他导入,一些模块级的全局变量在函数调用时也是None。



奇怪的是,这只是我们的分期环境(Ubuntu 12.04)中的一个问题。它在本地工作正常,这可能非常类似于使用额外的python包进行开发工作。有生产中也很好。



以前有没有人遇到过,有什么想法可能会导致吗?



以下是代码:

  import urllib 
import time
import urlparse

#Django从django.db.models.signals导入
从django.db导入post_delete
导入模型
from django.contrib.auth.models import User

从backends.cache.dualcache导入缓存

#活塞从管理器导入
TokenManager,ConsumerManager
从信号import consumer_post_delete

KEY_SIZE = 18
SECRET_SIZE = 32
VERIFIER_SIZE = 10

CONSUMER_STATES =(
('pending','Pending'),
('accepted','Accepted') ,
('取消','取消'),
('被拒绝','拒绝')



def generate_random(length = SECRET_SIZE):
return User.objects.make_random_password(length = length)


class Consumer(models.Model):
name = models.CharField(max_length = 255)
description = models.TextField()

key = models.CharField(max_length = KEY_SIZE)
secret = models.CharField(max_length = SECRET_SIZE)

status = models.CharField(max_length = 16,choices = CONSUMER_STATES,default ='pending')

objects = ConsumerManager()

def __unicode __(self):
return u带有%s的用户%s%(self.name,self.key)

def generate_random_codes(self):
key = User.objects.make_random_password(length = KEY_SIZE)
secret = generate_random(SECRET_SIZE)

而Consumer.objects.filter (key__exact = key,secret_exact = secret).count():
secret = generate_random(SECRET_SIZE)

self.key = key
self.secret = secret
self.save()

这里的工作,这意味着基本上是我在您的功能内重新输入您需要的内容:

  import urllib 
import time
import urlparse

#Django从django.db.models.signals导入
导入post_delete
从django.db导入模型
从django.contrib.auth.models import User

从backends.cache.dualcache导入缓存

#活塞从管理器导入
TokenManager,ConsumerManager
从信号import consumer_post_delete

KEY_SIZE = 18
SECRET_SIZE = 32
VERIFIER_SIZE = 10

CONSUMER_STATES =(
('pending','Pending'),
('accepted'
(已取消,已取消),
(被拒绝,拒绝)



def generate_random(length = SECRET_SIZE):
return User.objects.make_random_password(length = length)


class Consumer(models.Model):
name = models。 CharField(max_length = 255)
description = model s.TextField()

key = models.CharField(max_length = KEY_SIZE)
secret = models.CharField(max_length = SECRET_SIZE)

status = models.CharField (max_length = 16,choices = CONSUMER_STATES,default ='pending')

objects = ConsumerManager()

def __unicode __(self):
return u %s with key%s%(self.name,self.key)

def generate_random_codes(self):
来自piston.models import KEY_SIZE,SECRET_SIZE,Consumer
from django.contrib.auth.models import来自piston.models的用户
import_random

key = User.objects.make_random_password(length = KEY_SIZE)
secret = generate_random(SECRET_SIZE)

而Consumer.objects.filter(key__exact = key,secret__exact = secret).count():
secret = generate_random(SECRET_SIZE)

self.key = key
self.secret = secret
self.save()

这是堆栈跟踪。错误是由以下行引起的:

  key = User.objects.make_random_password(length = KEY_SIZE)

在generate_random_codes函数中。

 追溯:
文件/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/core/handlers/base.py在get_response
111.响应= callback(request,* callback_args,** callback_kwargs)
文件/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/contrib/admin/options.py wrapper
366. return self.admin_site.admin_view(view)(* args,** kwargs)
文件/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages /django/utils/decorators.py在_wrapped_view
91. response = view_func(request,* args,** kwargs)
文件/ sites / tellybug / shared / webserver / local / lib / python2 .7 / site-packages / django / views / decorators / cache.pyin _wrapped_view_func
89. response = view_func(request,* args,** kwargs)
文件/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/contrib/admin/sites。 pyin inner
196. return view(request,* args,** kwargs)
文件/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django /utils/decorators.pyin _wrapper
25. return bound_func(* args,** kwargs)
文件/sites/tellybug/shared/webserver/local/lib/python2.7/site- $ _
文件/ sites / tellybug / shared / webserver / local / lib中的/ django / utils / decorators.py在_wrapped_view
91. response = view_func(request,* args,** kwargs) python2.7 / site-packages / django / utils / decorators.pyin bound_func
21. return func(self,* args2,** kwargs2)
文件/ sites / tellybug / shared / webserver内部
224.中的/local/lib/python2.7/site-packages/django/db/transaction.pyreturn func(* args,** kwargs)
文件/ sites / tellybug / SH ared / webserver / local / lib / python2.7 / site-packages / django / contrib / admin / options.pyin add_view
970. form = ModelForm(initial = initial)
文件/ sites __init__中的/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/forms/models.py
234. self.instance = opts.model()
文件 __init__中的/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/db/models/base.py
349. val = field.get_default()
文件/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/db/models/fields/related.pyin get_default
983. field_default = super(ForeignKey,self ).get_default()
文件/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/db/models/fields/__init__.pyin get_default
379. return self.default()
文件/sites/tellybug/releases/b92109dd526607b2af92ad6b7f494f3f06e31bb2/webserver/tellybug/tbapp/models/tellybugapp.py generate_new_consumer
11. consumer.generate_random_codes()
文件/sites/tellybug/releases/b92109dd526607b2af92ad6b7f494f3f06e31bb2/webserver/tellybug/piston/models.pyin generate_random_codes
57. key = User.objects .make_random_password(length = KEY_SIZE)

异常类型:/ admin / tbapp / tellybugapp / add /
中的AttributeError异常值:'NoneType'对象没有属性'对象'

更新:这不是只是删除User对象 - 一些破坏整个上下文的东西函数。

  def generate_random_codes(self):

用于生成随机密钥/秘密配对在
添加其他数据代替save()之后,使用它。

c = Consumer()
c.name =我的消费者
c.description =从API制作小马的应用程序。
c.user = some_user_object
c.generate_random_codes()

import sys
打印全局,全局变量()
打印名称,__name__
打印包,__package__
打印Sys模块,sys.modules ['piston.models'] .__ dict__
key = User.objects.make_random_password(length = KEY_SIZE )

使用这些打印语句,输出为:



pre> Globals {'ColumnFamilyMap':None,'datetime':None,'KEY_SIZE':None,'TokenManager':None,'ConsistencyLevel':None,'Nonce' ,'uuid':无,'cache':无,'urllib':无,'__package__':无,'模型':无,'用户':无,....}
名称无
包无
Sys模块{'ColumnFamilyMap':< class'pycassa.columnfamilymap.ColumnFamilyMap'>'datetime':< type'datetime.datetime'>'KEY_SIZE':18,' NonceType':< class'piston.models.NonceT ype'>'OAuthToken':< class'piston.models.OAuthToken'>'TokenManager':< class'piston.managers.TokenManager'>'ConsistencyLevel':< class'pycassa.cassandra .withs,nonce:< class'piston.models.Nonce'>'uuid':< module'uuid'from'/usr/lib/python2.7/uuid.pyc' > ...}

请注意, __ package __ __ name __ 是未定义的,我认为这是不可能的,而该模块的sys.modules版本具有正确的 __ dict__ globals()的返回值是废话。

解决方案

这种情况发生在导入的模块中,该模块在垃圾回收之后仍然执行的功能。



由于您的代码不足以复制这个问题,这是一个简化的例子,显示行为。创建一个包含以下内容的文件,并从
Python命令行或另一个文件导入。如果您只是在顶级运行
,它不起作用。

  import sys 
import线程

x =foo

def run():
while True:
print%s%s\\\
% ,x)

threading.Thread(target = run).start()
sys.stdin.readline()

运行它:

  $ python 
>> > import evil_threading
< module'sys'(built-in)> foo

< module'sys'(built-in)> foo
...按Ctrl-C
无无

无无
...按Ctrl-\杀死Python解释器

在Python关机期间,模块设置为这是一个晦涩的Python行为,已在3.4中删除
在此示例中,终止主线程导致关闭,但其他线程仍在运行,因此它将模块视为



有一个更简单的例子从这里通过从sys.modules直接删除模块引用来做同样的事情。

  import sys 
print sys
del sys.modules ['__ main__']
print sys


Update: some more debugging info at the bottom of this post, which reveals something very screwy in the python state.

I have a module which imports, among other things, the django User object.

The import works fine, and the code loads. However, when you call a function in that module that uses the User object, it errors saying that User is a NoneType.

There are also a number of other imports, and some module level global variables which are also None by the time the function is called.

Oddly, this is only a problem in our staging environments (Ubuntu 12.04). It works fine locally, which probably most closely resembles staging with extra python packages for dev work. Also fine in production.

Has anyone come across this before, and have any ideas what might cause it?

Here's the code:

import urllib
import time
import urlparse

# Django imports
from django.db.models.signals import post_delete
from django.db import models
from django.contrib.auth.models import User

from backends.cache.dualcache import cache

# Piston imports
from managers import TokenManager, ConsumerManager
from signals import consumer_post_delete

KEY_SIZE = 18
SECRET_SIZE = 32
VERIFIER_SIZE = 10

CONSUMER_STATES = (
    ('pending', 'Pending'),
    ('accepted', 'Accepted'),
    ('canceled', 'Canceled'),
    ('rejected', 'Rejected')
)


def generate_random(length=SECRET_SIZE):
    return User.objects.make_random_password(length=length)


class Consumer(models.Model):
    name = models.CharField(max_length=255)
    description = models.TextField()

    key = models.CharField(max_length=KEY_SIZE)
    secret = models.CharField(max_length=SECRET_SIZE)

    status = models.CharField(max_length=16, choices=CONSUMER_STATES, default='pending')

    objects = ConsumerManager()

    def __unicode__(self):
        return u"Consumer %s with key %s" % (self.name, self.key)

    def generate_random_codes(self):
        key = User.objects.make_random_password(length=KEY_SIZE)
        secret = generate_random(SECRET_SIZE)

        while Consumer.objects.filter(key__exact=key, secret__exact=secret).count():
            secret = generate_random(SECRET_SIZE)

        self.key = key
        self.secret = secret
        self.save()

and here's the work around, which means basically to import what you need again inside the function:

import urllib
import time
import urlparse

# Django imports
from django.db.models.signals import post_delete
from django.db import models
from django.contrib.auth.models import User

from backends.cache.dualcache import cache

# Piston imports
from managers import TokenManager, ConsumerManager
from signals import consumer_post_delete

KEY_SIZE = 18
SECRET_SIZE = 32
VERIFIER_SIZE = 10

CONSUMER_STATES = (
    ('pending', 'Pending'),
    ('accepted', 'Accepted'),
    ('canceled', 'Canceled'),
    ('rejected', 'Rejected')
)


def generate_random(length=SECRET_SIZE):
    return User.objects.make_random_password(length=length)


class Consumer(models.Model):
    name = models.CharField(max_length=255)
    description = models.TextField()

    key = models.CharField(max_length=KEY_SIZE)
    secret = models.CharField(max_length=SECRET_SIZE)

    status = models.CharField(max_length=16, choices=CONSUMER_STATES, default='pending')

    objects = ConsumerManager()

    def __unicode__(self):
        return u"Consumer %s with key %s" % (self.name, self.key)

    def generate_random_codes(self):
        from piston.models import KEY_SIZE, SECRET_SIZE, Consumer
        from django.contrib.auth.models import User
        from piston.models import generate_random

        key = User.objects.make_random_password(length=KEY_SIZE)
        secret = generate_random(SECRET_SIZE)

        while Consumer.objects.filter(key__exact=key, secret__exact=secret).count():
            secret = generate_random(SECRET_SIZE)

        self.key = key
        self.secret = secret
        self.save()

Here's the stack trace. The error is caused by the line:

key = User.objects.make_random_password(length=KEY_SIZE)

in the generate_random_codes function.

Traceback:
File "/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  111.                         response = callback(request, *callback_args, **callback_kwargs)
File "/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/contrib/admin/options.py" in wrapper
  366.                 return self.admin_site.admin_view(view)(*args, **kwargs)
File "/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
  91.                     response = view_func(request, *args, **kwargs)
File "/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
  89.         response = view_func(request, *args, **kwargs)
File "/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/contrib/admin/sites.py" in inner
  196.             return view(request, *args, **kwargs)
File "/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapper
  25.             return bound_func(*args, **kwargs)
File "/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
  91.                     response = view_func(request, *args, **kwargs)
File "/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/utils/decorators.py" in bound_func
  21.                 return func(self, *args2, **kwargs2)
File "/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/db/transaction.py" in inner
  224.                 return func(*args, **kwargs)
File "/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/contrib/admin/options.py" in add_view
  970.             form = ModelForm(initial=initial)
File "/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/forms/models.py" in __init__
  234.             self.instance = opts.model()
File "/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/db/models/base.py" in __init__
  349.                 val = field.get_default()
File "/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/db/models/fields/related.py" in get_default
  983.         field_default = super(ForeignKey, self).get_default()
File "/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/db/models/fields/__init__.py" in get_default
  379.                 return self.default()
File "/sites/tellybug/releases/b92109dd526607b2af92ad6b7f494f3f06e31bb2/webserver/tellybug/tbapp/models/tellybugapp.py" in generate_new_consumer
  11.     consumer.generate_random_codes()
File "/sites/tellybug/releases/b92109dd526607b2af92ad6b7f494f3f06e31bb2/webserver/tellybug/piston/models.py" in generate_random_codes
  57.   key = User.objects.make_random_password(length=KEY_SIZE)

Exception Type: AttributeError at /admin/tbapp/tellybugapp/add/
Exception Value: 'NoneType' object has no attribute 'objects'

Update: It's not something just deleting the User object - something is wrecking the entire context in the function.

def generate_random_codes(self):
    """
    Used to generate random key/secret pairings. Use this after you've
    added the other data in place of save().

    c = Consumer()
    c.name = "My consumer"
    c.description = "An app that makes ponies from the API."
    c.user = some_user_object
    c.generate_random_codes()
    """
    import sys
    print "Globals", globals()
    print "Name ", __name__
    print "Package ", __package__
    print "Sys modules", sys.modules['piston.models'].__dict__
    key = User.objects.make_random_password(length=KEY_SIZE)

With these print statements, the output is:

Globals {'ColumnFamilyMap': None, 'datetime': None, 'KEY_SIZE': None, 'TokenManager': None, 'ConsistencyLevel': None, 'Nonce': None, 'uuid': None, 'cache': None, 'urllib': None, '__package__': None, 'models': None, 'User': None,  .... }
Name  None
Package  None
Sys modules {'ColumnFamilyMap': <class 'pycassa.columnfamilymap.ColumnFamilyMap'>, 'datetime': <type 'datetime.datetime'>, 'KEY_SIZE': 18, 'NonceType': <class 'piston.models.NonceType'>, 'OAuthToken': <class 'piston.models.OAuthToken'>, 'TokenManager': <class 'piston.managers.TokenManager'>, 'ConsistencyLevel': <class 'pycassa.cassandra.ttypes.ConsistencyLevel'>, 'Nonce': <class 'piston.models.Nonce'>, 'uuid': <module 'uuid' from '/usr/lib/python2.7/uuid.pyc'>,  ...}

Note that both __package__ and __name__ are undefined, which I thought was pretty much impossible, and that while the sys.modules version of the module has a correct __dict__, the return value from globals() is nonsense.

解决方案

This happens to a function in an imported module that is still executing after that module is garbage collected.

Since your code isn't enough to reproduce the issue, here's a simplified example that shows the behaviour. Create a file containing the following and import it either from the Python command line or from another file. It doesn't work if you just run it at the top level.

import sys
import threading

x = "foo"

def run():
    while True:
        print "%s %s\n" % (sys, x)

threading.Thread(target = run).start()
sys.stdin.readline()

Running it:

$ python
>>> import evil_threading
<module 'sys' (built-in)> foo

<module 'sys' (built-in)> foo
... press Ctrl-C
None None

None None
... press Ctrl-\ to kill the Python interpreter

During Python shutdown, modules are set to None. This is an obscure Python behaviour that was removed in 3.4. In this example, terminating the main thread results in shutdown, but the other thread is still running, so it sees the modules as None.

There is a simpler example from here which does the same thing by deleting the module reference directly from sys.modules.

import sys
print sys
del sys.modules['__main__']
print sys

这篇关于导入的模块在运行功能时变为“无”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆