Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/304.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中使用属性时Class.foo和instance.foo的不同行为_Python_Python 3.x_Python 2.7 - Fatal编程技术网

在Python中使用属性时Class.foo和instance.foo的不同行为

在Python中使用属性时Class.foo和instance.foo的不同行为,python,python-3.x,python-2.7,Python,Python 3.x,Python 2.7,我的问题是: 当我使用“属性”控制一个变量的访问时 instance.var将正确返回实际值, 而Class.var将返回属性对象本身(例如位于0x7fc5215ac788的属性对象) 但是,当我使用等效方法(例如描述符)并重写\uuuu get\uuuu和\uuu set\uuu方法时, instance.var和Class.var都可以返回实际值,而不是对象本身 那么为什么他们的行为如此不同呢 我猜这是因为my描述符中实现的一些默认函数具有魔力,那么它们是什么呢 更新: 出现上述问题的原因

我的问题是:

当我使用“属性”控制一个变量的访问时

instance.var
将正确返回实际值, 而
Class.var
将返回属性对象本身(例如位于0x7fc5215ac788的
属性对象)

但是,当我使用等效方法(例如描述符)并重写
\uuuu get\uuuu
\uuu set\uuu
方法时,
instance.var
Class.var
都可以返回实际值,而不是对象本身

那么为什么他们的行为如此不同呢

我猜这是因为my描述符中实现的一些默认函数具有魔力,那么它们是什么呢


更新:

出现上述问题的原因是,在
属性
中实现的
\uuuu get\uuuu
函数将确定它是由实例调用还是由类调用,当它由类调用时,它将返回对象本身(即self)

但是由于
\uuuu set\uuu
函数没有
类型
cls
参数,并且根据我的测试,
\uu set\uuu
函数无法捕获
Class.var=5

因此,我想知道我们可以使用什么钩子来定制类变量级别分配
class.var=value

当您执行
MyClass时。某些描述符
,显然没有实例可以传递给描述符,因此它是用
obj=None
调用的:

##### Case 1, use property #####
class Case1:
    # ignore getter and setter for property
    var = property(getter, setter, None, None)

##### Case 2, use equivalent methods ####
class Descriptor:
    def __get__(self, obj, type=None):
        return None
    def __set__(self, obj, val):
        pass

class Case2:
     var = Descriptor()
这就是所有涉及的“魔力”

现在,如果您想知道为什么这不是默认值:有一些用例可以为在类上查找的描述符返回其他内容—例如方法(是的,Python函数是描述符—它们的
\uuuuu get\uuuu
方法返回
方法
对象,该对象实际上是实例周围的可调用包装器(如果有的话),类别及功能):

Foo.meth=lambda self:42 >>>氟甲基苯丙胺 >>>Foo().meth >>>Foo.meth(Foo()) 42
btw,我发现Python确实有很多“implit”行为,例如,像“instance.var”如何涉及“\u getattribute\uu”和最后涉及“\u getattr\uu”,在很多书中几乎没有提到。我想知道是否有一些很好的材料涵盖了这类主题?关于什么?就我而言,这是相当明确的,特别是因为Python是为数不多的公开暴露其对象模型内部并让您与之挂钩的OOPL之一。哦,是的:
\uuuu getattr\uuuu
仅在实现时调用(在
对象
中没有默认实现),并且作为最后手段,如果之前没有解决该属性。根据我的测试,类变量级别分配
class.var=value
不能被
\uuuu set\uuuu
函数捕获,即使
var
是描述符,因为它没有
type
cls
参数。那么你知道我可以用什么钩子来进行这种定制吗?
>>> class Desc(object):
...     def __get__(self, obj, cls=None):
...         print "obj : {} - cls : {}".format(obj, cls)
...         return 42
... 
>>> class Foo(object):
...    bar = Desc()
... 
>>> Foo.bar
obj : None - cls : <class '__main__.Foo'>
42
>>> Foo().bar
obj : <__main__.Foo object at 0x7fd285cf4a90> - cls : <class '__main__.Foo'>
42
>>> 
>>> class Desc2(object):
...     def __get__(self, obj, cls=None):
...         if obj is None:
...             return self
...         return 42
... 
>>> Foo.baaz = Desc2()
>>> Foo.baaz
<__main__.Desc2 object at 0x7fd285cf4b10>
>>> Foo().baaz
42
>>> 
>>> Foo.meth = lambda self: 42
>>> Foo.meth
<unbound method Foo.<lambda>>
>>> Foo().meth
<bound method Foo.<lambda> of <__main__.Foo object at 0x7fd285cf4bd0>>
>>> Foo.meth(Foo())
42