Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python _;获取_;静态实例和成员之间的差异_Python - Fatal编程技术网

Python _;获取_;静态实例和成员之间的差异

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

我很难理解静态对象和成员对象(那些在构造函数中创建的对象)之间的区别

以下操作将运行被覆盖的get():

但是,如果我把b拉到构造函数中,它不会:

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)
where
a=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
的描述符)和其他根本不是描述符的类变量的优先级低于实例变量。