Python _;获取_;静态实例和成员之间的差异
我很难理解静态对象和成员对象(那些在构造函数中创建的对象)之间的区别 以下操作将运行被覆盖的get(): 但是,如果我把b拉到构造函数中,它不会:Python _;获取_;静态实例和成员之间的差异,python,Python,我很难理解静态对象和成员对象(那些在构造函数中创建的对象)之间的区别 以下操作将运行被覆盖的get(): 但是,如果我把b拉到构造函数中,它不会: class A(object): class B(object): def __init__(self, initval=None, name='var'): self.val = initval self.name = name def __get__(sel
class A(object):
class B(object):
def __init__(self, initval=None, name='var'):
self.val = initval
self.name = name
def __get__(self, obj, objtype):
print('B Retrieving', self.name)
return self.val
def __init__(self)):
self.b = A.B(10, 'var "b"')
我真的很想在后者中实现这一点,也许这不是正确的方式
有人能解释一下在调用print(a.b)
wherea=a()
时这里发生了什么吗
另外,是否有方法让
print(a.b)
从b调用成员函数?您的b
对象是一个描述符。这意味着当Python将其绑定为类变量时,它与大多数其他对象的处理方式不同。具体地说,在类变量代码中,A().b
被转换为函数调用A.\uuuuu class\uuuuuuuuuuuu dict\uuuuu[“b”]。\uuuuu get\uuuuu(A(),A)
。Python在内部使用描述符。这是方法绑定和大多数\uuuuuuuuuuuuuuuuuu
方法工作原理的一部分
当描述符存储为实例变量时,不会给予特殊处理。查找作为描述符的实例变量只会获取描述符对象,而不是调用其\uuuuu get\uuuu
方法的结果
如果您需要能够设置描述符在每个实例的基础上返回的值,您可能希望让描述符检查调用它的实例上的属性,而不是其本身的属性:
class B(object):
def __init__(self, name='var'):
self.name = name
def __get__(self, obj, objtype):
print('B Retrieving', self.name)
return obj._bval # lookup the value on the object, not on the descriptor
class A(object):
b = B() # assign the descriptor as an class variable
def __init__(self):
self._bval = 10 # initialize the value
请注意,我对您的课程不感兴趣,主要是为了清楚起见。在
A
中定义B
类并不是完全错误的,但它让人困惑,而且与将B
作为顶级类相比,没有任何实际好处。您的B
对象是一个描述符。这意味着当Python将其绑定为类变量时,它与大多数其他对象的处理方式不同。具体地说,在类变量代码中,A().b
被转换为函数调用A.\uuuuu class\uuuuuuuuuuuu dict\uuuuu[“b”]。\uuuuu get\uuuuu(A(),A)
。Python在内部使用描述符。这是方法绑定和大多数\uuuuuuuuuuuuuuuuuu
方法工作原理的一部分
当描述符存储为实例变量时,不会给予特殊处理。查找作为描述符的实例变量只会获取描述符对象,而不是调用其\uuuuu get\uuuu
方法的结果
如果您需要能够设置描述符在每个实例的基础上返回的值,您可能希望让描述符检查调用它的实例上的属性,而不是其本身的属性:
class B(object):
def __init__(self, name='var'):
self.name = name
def __get__(self, obj, objtype):
print('B Retrieving', self.name)
return obj._bval # lookup the value on the object, not on the descriptor
class A(object):
b = B() # assign the descriptor as an class variable
def __init__(self):
self._bval = 10 # initialize the value
请注意,我对您的课程不感兴趣,主要是为了清楚起见。在
A
中定义B
类并不是完全错误的,但它会让人困惑,而且与将B
作为顶级类相比,它没有带来任何实际好处。通过实现\u get\uuuuuu
,您将类B
变成了一个顶级类。描述符是通过对实例执行自定义逻辑来处理属性访问的对象
为了使描述符工作,您需要将它们声明为类型上的成员。只有这样,Python才能正确地调用对象的\uuuuuuuuuuuuuuuuuuuuuuuu
方法
之所以执行self.b=SomeDescriptor()
不起作用,是因为通过将某些内容分配给self.b
,您直接更改了对象的底层\uuuuu dict\uuu
:
>>> class A(object): pass
>>> x = A()
>>> x.b = B(10, '')
>>> x.__dict__
{'b': <__main__.B object at 0x000000437141F208>}
通过实现
\uuu get\uuu
,您将类B
变成了一个。描述符是通过对实例执行自定义逻辑来处理属性访问的对象
为了使描述符工作,您需要将它们声明为类型上的成员。只有这样,Python才能正确地调用对象的\uuuuuuuuuuuuuuuuuuuuuuuu
方法
之所以执行self.b=SomeDescriptor()
不起作用,是因为通过将某些内容分配给self.b
,您直接更改了对象的底层\uuuuu dict\uuu
:
>>> class A(object): pass
>>> x = A()
>>> x.b = B(10, '')
>>> x.__dict__
{'b': <__main__.B object at 0x000000437141F208>}
嵌套类几乎永远不会按照您期望的方式工作。除非您完全知道自己在做什么,否则不要使用它们。嵌套类几乎永远不会按照您期望的方式工作。除非您完全知道自己在做什么,否则不要使用它们。说Python只在对象dict之后检查类dict是不太正确的(尽管在当前情况下这基本上是正确的)。Python实际上首先检查类dict,如果有数据描述符(如
属性
),则它优先于任何同名的实例变量。非数据描述符(即具有\uuuuu get\uuuuu
方法的描述符,但不具有\uuuu set\uuuu
或\uuuu delete\uuuu
的描述符)和其他根本不是描述符的类变量的优先级低于实例变量。说Python只在对象dict之后检查类dict是不太正确的Python实际上首先检查类dict,如果有数据描述符(如属性
),它优先于任何同名的实例变量。非数据描述符(也就是说,具有\uuuuu get\uuuu
方法,但不具有\uuuu set\uuuu
或\uuu delete\uuuuu
的描述符)和其他根本不是描述符的类变量的优先级低于实例变量。