更新:在这篇文章的底部有一些更多的调试信息,它揭示了python状态下非常棘手的东西.
我有一个模块,可以导入django User对象等.
导入工作正常,代码加载.但是,当您在该模块中调用使用User对象的函数时,它会错误地说User是NoneType.
还有许多其他导入,以及一些模块级全局变量,在调用函数时也是None.
奇怪的是,这只是我们的临时环境(Ubuntu 12.04)中的一个问题.它在本地工作正常,这可能最接近于使用额外的python包进行开发工作.生产也很好.
有没有人遇到过这个,并有任何想法可能导致它?
这是代码:
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()
Run Code Online (Sandbox Code Playgroud)
这是解决方法,这意味着基本上在函数内再次导入你需要的东西:
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()
Run Code Online (Sandbox Code Playgroud)
这是堆栈跟踪.该错误是由该行引起的:
key = User.objects.make_random_password(length=KEY_SIZE)
Run Code Online (Sandbox Code Playgroud)
在generate_random_codes函数中.
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'
Run Code Online (Sandbox Code Playgroud)
更新:这不仅仅是删除User对象 - 某些东西正在破坏函数中的整个上下文.
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)
Run Code Online (Sandbox Code Playgroud)
使用这些打印语句,输出为:
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'>, ...}
Run Code Online (Sandbox Code Playgroud)
请注意这两个__package__和__name__是不确定的,我认为是非常不可能的,而且,虽然模块的这个sys.modules版本有一个正确__dict__的返回值从globals()是无稽之谈.
这发生在导入模块中的一个函数中,该模块在该模块被垃圾收集后仍在执行.
由于您的代码不足以重现问题,因此这是一个显示行为的简化示例.创建包含以下内容的文件,并从Python命令行或从其他文件导入它.如果你只是在顶层运行它不起作用.
import sys
import threading
x = "foo"
def run():
while True:
print "%s %s\n" % (sys, x)
threading.Thread(target = run).start()
sys.stdin.readline()
Run Code Online (Sandbox Code Playgroud)
运行它:
$ 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
Run Code Online (Sandbox Code Playgroud)
在Python关闭期间,模块设置为None.这是一个不起眼的Python行为,已在3.4中删除.在此示例中,终止主线程导致关闭,但另一个线程仍在运行,因此它将模块视为None.
这里有一个更简单的例子,通过直接从sys.modules中删除模块引用来做同样的事情.
import sys
print sys
del sys.modules['__main__']
print sys
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3131 次 |
| 最近记录: |