2

我知道setattr当我们在一个对象之外时我们必须使用方法。但是,我在使用 unicode 键调用时遇到了麻烦setattr,导致我__setattr__直接使用。

class MyObject(object):
    def __init__(self):
        self.__dict__["properties"] = dict()
    def __setattr__(self, k, v):
        self.properties[k] = v
obj = MyObject()

我得到以下内容obj.properties

  • setattr(obj, u"é", u"à"): 引发 UnicodeEncodeError
  • setattr(obj, "é", u"à"){'\xc3\xa9': u'\xe0'}
  • obj.__setattr__(u"é", u"à"){u'\xe9': u'\xe0'}

我不明白为什么 Python 会出现这些差异

4

2 回答 2

0

蟒蛇2.7?仅限 Ascii 标识符。这包括您在 2) 中的代码 - ascii 重音但不包括 .1) - unicode 重音。

Python中的Unicode标识符?

3) 涉及您在字典中设置 unicode键。合法的。

请注意, __setattr__几乎永远不会像您一样使用。它旨在为对象设置属性。不要拦截它并将它们填充到内部 dict 属性中。我也避免使用属性作为名称,与 get/Set 意义上的属性混淆。

通常你想使用 setattr,而不是双下划线变体。不像你的开场白。

您通常也不调用双下划线方法,您定义它们,Python 的底层数据协议代表您调用它们。有点像 JavaBeans 获取/设置隐式调用(我认为)。

__setattr__ 可能很棘手。如果您不小心,它会以意想不到的方式阻止“设置活动”。

这是一个愚蠢的例子,

class Foo(object):

    def __setattr__(self, attrname, value):
        """ let's uppercase variables starting with k"""

        if attrname.lower().startswith("k"):
            self.__dict__[attrname.upper()] = value

foo = Foo()

foo.kilometer = 1000
foo.meter = 1

print "foo.KILOMETER:%s" % getattr(foo, "KILOMETER", "unknown")
print "foo.meter:%s" % getattr(foo, "meter", "unknown")
print "foo.METER:%s" % getattr(foo, "METER", "unknown")

输出:

foo.KILOMETER:1000
foo.meter:unknown
foo.METER:unknown

你需要有一个else之后if

        else:
            self.__dict__[attrname] = value

输出:

foo.KILOMETER:1000
foo.meter:1
foo.METER:unknown

最后,如果您刚刚开始并且 unicode 很重要,我会评估 Python 2 vs 3 - 3 具有更好、统一的 unicode 支持。您可能需要也可能不需要使用 2.7 而不是 3,但 unicode “推向” 3 的原因有很多。

于 2016-04-21T14:30:43.903 回答
0

Python 2 不允许使用 unicode 标识符:

>>> é = 3
  File "<stdin>", line 1
    é = 3
    ^
SyntaxError: invalid syntax

大概它在这一点上如此坚持以至于您无法在尝试时解决它,因为setattr在调用__setattr__. print您可以通过在开头插入 a 来显示这一点__setattr__:什么都不会打印,因此问题不在您的代码中。

于 2016-04-21T14:33:41.047 回答