我的班级有一个词典,例如:
class MyClass(object):
def __init__(self):
self.data = {'a': 'v1', 'b': 'v2'}
Run Code Online (Sandbox Code Playgroud)
然后我想使用dict的密钥和MyClass实例来访问dict,例如:
ob = MyClass()
v = ob.a # Here I expect ob.a returns 'v1'
Run Code Online (Sandbox Code Playgroud)
我知道这应该由__getattr__实现,但我是Python的新手,我不知道如何实现它.
jam*_*lak 60
class MyClass(object):
def __init__(self):
self.data = {'a': 'v1', 'b': 'v2'}
def __getattr__(self, attr):
return self.data[attr]
Run Code Online (Sandbox Code Playgroud)
>>> ob = MyClass()
>>> v = ob.a
>>> v
'v1'
Run Code Online (Sandbox Code Playgroud)
实施时要小心__setattr__,你需要做一些修改:
class MyClass(object):
def __init__(self):
# prevents infinite recursion from self.data = {'a': 'v1', 'b': 'v2'}
# as now we have __setattr__, which will call __getattr__ when the line
# self.data[k] tries to access self.data, won't find it in the instance
# dictionary and return self.data[k] will in turn call __getattr__
# for the same reason and so on.... so we manually set data initially
super(MyClass, self).__setattr__('data', {'a': 'v1', 'b': 'v2'})
def __setattr__(self, k, v):
self.data[k] = v
def __getattr__(self, k):
# we don't need a special call to super here because getattr is only
# called when an attribute is NOT found in the instance's dictionary
try:
return self.data[k]
except KeyError:
raise AttributeError
Run Code Online (Sandbox Code Playgroud)
>>> ob = MyClass()
>>> ob.c = 1
>>> ob.c
1
Run Code Online (Sandbox Code Playgroud)
如果您不需要设置属性,只需使用namedtuple例如.
>>> from collections import namedtuple
>>> MyClass = namedtuple("MyClass", ["a", "b"])
>>> ob = MyClass(a=1, b=2)
>>> ob.a
1
Run Code Online (Sandbox Code Playgroud)
如果你想要默认参数,你可以围绕它编写一个包装类:
class MyClass(namedtuple("MyClass", ["a", "b"])):
def __new__(cls, a="v1", b="v2"):
return super(MyClass, cls).__new__(cls, a, b)
Run Code Online (Sandbox Code Playgroud)
或者它看起来更好看作为一个功能:
def MyClass(a="v1", b="v2", cls=namedtuple("MyClass", ["a", "b"])):
return cls(a, b)
Run Code Online (Sandbox Code Playgroud)
>>> ob = MyClass()
>>> ob.a
'v1'
Run Code Online (Sandbox Code Playgroud)
迟到了,但找到了两个非常好的资源,可以更好地解释这一点(恕我直言).
正如解释在这里,你应该使用self.__dict__从内部访问的字段__getattr__,以避免无限递归.提供的示例是:
Run Code Online (Sandbox Code Playgroud)def __getattr__(self, attrName): if not self.__dict__.has_key(attrName): value = self.fetchAttr(attrName) # computes the value self.__dict__[attrName] = value return self.__dict__[attrName]
注意:在第二行(上图)中,更多Pythonic方式(has_key显然甚至在Python 3中删除):
if attrName not in self.__dict__:
Run Code Online (Sandbox Code Playgroud)
在其他资源解释说,__getattr__只有当对象没有找到,则调用,并且hasattr总是返回True如果有一个实现__getattr__.它提供了以下示例,以演示:
Run Code Online (Sandbox Code Playgroud)class Test(object): def __init__(self): self.a = 'a' self.b = 'b' def __getattr__(self, name): return 123456 t = Test() print 'object variables: %r' % t.__dict__.keys() #=> object variables: ['a', 'b'] print t.a #=> a print t.b #=> b print t.c #=> 123456 print getattr(t, 'd') #=> 123456 print hasattr(t, 'x') #=> True
| 归档时间: |
|
| 查看次数: |
39879 次 |
| 最近记录: |