Python是什么意思“AttributeError:'unicode'对象没有属性'has_key'”

时间:2009-08-21 23:26:54

标签: python google-app-engine

我想问一下它是什么意思“AttributeError:'unicode'对象没有属性'has_key'” 这是完整的堆栈跟踪:

Traceback (most recent call last):
  File     "D:\Projects\GoogleAppEngine\google_appengine\google\appengine\ext\webapp\__init__.py", line 509, in __call__
    handler.post(*groups)
  File "D:\Projects\workspace\foo\src\homepage.py", line 71, in post
    country=postedcountry
  File "D:\Projects\GoogleAppEngine\google_appengine\google\appengine\ext\db\__init__.py", line 656, in __init__
    prop.__set__(self, value)
  File "D:\Projects\GoogleAppEngine\google_appengine\google\appengine\ext\db\__init__.py", line 2712, in __set__
    value = self.validate(value)
  File "D:\Projects\GoogleAppEngine\google_appengine\google\appengine\ext\db\__init__.py", line 2742, in validate
    if value is not None and not value.has_key():
AttributeError: 'unicode' object has no attribute 'has_key'

让我再详细介绍一下情况:

  • 首先,我创建了models.py,其中包含用于CMSRequest的db.Model,其具有引用CMSCountry类的属性country

    class CMSRequest(db.Model):
      country = db.ReferenceProperty(CMSCountry, required=True)
    
    class CMSCountry(db.Model):
      name = db.StringProperty(required=True)
    
  • 然后,我创建了一个bulkloader类来将数据导入CMSCountry

  • 在表单中,用户可以从下拉列表框中选择国家/地区,结果将被回发并保存到CMSRequest对象

    def post(self):
      postedcountry = self.request.get('country')
      cmsRequest = models.CMSRequest(postedcountry)
    

也许我找到了我的问题的解决方案,这是因为我没有将CMSCountry的已发布密钥转换回保存到CMSRequest。

谢谢大家!

6 个答案:

答案 0 :(得分:6)

在这一行:

if value is not None and not value.has_key():

value是一个unicode字符串。看起来代码期望它是db.Model

(从我所看到的,has_keydb.Model的方法,以及Python字典的方法,但这必须是db.Model,因为它被调用没有争论。)

您是否将字符串传递给期望db.Model

的GAE API

答案 1 :(得分:3)

您的问题是,postedcountry是一个字符串而不是国家/地区对象。从self.request.get检索的值是浏览器传递的变量的字符串值。

您需要使用某些GQL查找国家/地区对象。具体如何操作将取决于HTML表单的国家/地区字段的确切位置,对象密钥?,国家/地区名称?

def post(self):
  postedcountry = self.request.get('country')

  # <-------- Need to look up a country here !!!!!

  cmsRequest = models.CMSRequest(country=postedcountry)

答案 2 :(得分:2)

注意:通常在Python中使用“映射”类型(字典和类似字典......例如各种类型的dbm(索引文件)和一些DBMS / ORM接口......)将实现has_key()方法。

当你期望有某种字典或其他映射对象引用时,你已经在这个语句中得到了一个Unicode(字符串)对象。

一般来说, AttributeError 意味着您已经纠结了对象绑定(变量赋值)。除了你想要的类型之外,你给某个对象命名了。 (或者有时它意味着你有一个像“.haskey()”而不是has_key()等等的错字。)

BTW:使用has_key()有点过时了。通常情况下,最好使用Python in 运算符(隐式调用__contains__()}来测试容器,这些运算符适用于列表,字符串和其他序列以及映射类型)。

即使value.has_key()是字典,value也会引发错误,因为.has_key()方法需要参数。

在您的代码中,我会明确地测试if postedcountry is not None: ...或者我会为.get()提供“postscountry”的(可选)默认值。

您希望如何处理request没有 postedcountry 的情况?你想假设它是从某个特定的默认值发布的吗?强制重定向到某个页面,要求用户为该表单元素提供值?提醒西班牙宗教裁判所?

答案 3 :(得分:1)

如果您阅读了追溯,它会告诉您到底发生了什么:

    if value is not None and not value.has_key():
AttributeError: 'unicode' object has no attribute 'has_key'

这说明您使用的value变量没有has_key属性。并且,它告诉你的是你的value变量不是字典,因为它看起来像你期待的......相反,它是一个unicode对象,它基本上是一个字符串。

答案 4 :(得分:1)

您正在尝试将字符串设置为ReferenceProperty。 CMSCountry的“country”字段是db.ReferenceProperty,它接受db.Key或CMSCountry对象,但您尝试将其设置为字符串。

你应该这样做:

def post(self):
  postedcountry = self.request.get('country')
  country = models.CMSCountry.all().filter('name =', postedcountry)
  if not country:
    # Couldn't find the country
  else:
    cmsRequest = models.CMSRequest(country=country)

但是请对file a bug做一些相当无用的错误消息。

答案 5 :(得分:0)

字典对象的has_key()方法在3.0中已弃用 - 请改用“in”表达式。如果您在3.x中使用旧库,则必须更改代码以适应它。