疑问
class Function:...
def __get__(self, obj, objtype=None):
'''Simulate func_descr_get() in Objects/funcobject.c'''
if obj is None:
return self
return MethodType(self, obj)
怎么确定obj是否为none?
这个 __get__()的触发条件是什么?
@FishC __get__()方法是用于描述符(descriptor)的特殊方法之一,它在描述符被获取时触发。在这段代码中,__get__()方法用于实现描述符协议,即当我们通过实例访问描述符时,它会被调用。
在这段代码中,obj代表实例对象,objtype代表实例所属的类。在描述符被获取时,__get__()方法会判断obj是否为None,以确定是通过实例还是类访问描述符。如果obj为None,则说明是通过类访问描述符,直接返回描述符本身;如果obj不为None,则说明是通过实例访问描述符,创建一个绑定方法,并返回该方法。
举个例子来说明:
class Function:
def __get__(self, obj, objtype=None):
if obj is None:
return self
return MethodType(self, obj)
class MyClass:
func = Function()
my_obj = MyClass()
# 通过实例访问描述符
my_obj.func()
# 通过类访问描述符
MyClass.func()
当通过实例my_obj访问描述符func时,__get__()方法会被调用,此时obj为my_obj,objtype为MyClass。由于obj不为None,就会创建一个绑定方法并返回。
当通过类MyClass访问描述符func时,__get__()方法同样会被调用,但此时obj为None,所以直接返回描述符本身。
希望这个解答能对你有所帮助!
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 本帖最后由 isdkz 于 2024-4-11 23:37 编辑
拥有 __get__ 方法的对象会成为描述符,描述符的 __get__ 方法会在作为类属性被引用的时候触发,
并传入引用的实例对象作为描述符 __get__ 方法的第二个参数:
当引用对象为类的时候,描述符的__get__方法接收到的第二个参数即obj为None,因为引用对象为类,并没有实例,所以传入None
当引用对象为类的实例的时候,描述符的__get__方法接收到的第二个参数即obj为实例本身
代码举例:
# 定义一个描述符类
class Desc:
def __get__(*args):
print("描述符被引用")
print("传入了参数:", args)
# 定义一个测试类
class Test:
...
# 实例化一个描述符对象
d = Desc()
# 实例化一个测试对象
t = Test()
# 描述符作为对象属性被引用的时候不会触发
t.d = d
print(t.d) # 输出:<__main__.Desc object at 0x000001537CC37C70>
print(Test.d) # 输出:AttributeError: type object 'Test' has no attribute 'd'
del t.d # 删除之前的 t.d
Test.d = d
#描述符作为类属性被类引用的时候,描述符的__get__方法接收到的第二个参数即obj为None
print(Test.d)
# 输出:
#描述符被引用
#传入了参数: (<__main__.Desc object at 0x000001537CC37C70>, None, <class '__main__.Test'>)
#描述符作为类属性被实例引用的时候,描述符的__get__方法接收到的第二个参数即obj为实例本身
print(t.d)
# 输出:
#描述符被引用
#传入了参数: (<__main__.Desc object at 0x000001537CC37C70>, <__main__.Test object at 0x000001537CE23E20>, <class '__main__.Test'>) 为了能给尊贵的鱼油解释,小人也是废了些心机的,如果有帮助的话请不要忘了给个最佳哦{:10_319:} class C:
@staticmethod
def funC():
print('i love you')
这个不用语法糖的话,应该是怎么写的?@FishC 亦又 发表于 2024-04-12 15:38
class C:
@staticmethod
def funC():
...
在不使用语法糖的情况下,可以通过直接定义类的静态方法来实现相同的功能。以下是一个不使用语法糖的示例代码:
class C:
def funC():
print('i love you')
funC = staticmethod(funC)
# 调用静态方法
C.funC()
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 class G:
@classmethod
@property
def __doc__(cls):
return f'A doc for {cls.__name__!r}'
这个不用语法糖的话,应该是怎么写的?@FishC 亦又 发表于 2024-04-12 17:37
class G:
@classmethod
@property
def ...
嗨,@FishC!没有使用语法糖时,你可以这样编写代码:
class G:
@classmethod
@property
def __doc__(cls):
return 'A doc for ' + repr(cls.__name__)
这段代码与使用语法糖的效果相同。首先,`@property`装饰器将`__doc__()`方法转换为属性,以便我们可以直接访问它而不是调用它。然后,`@classmethod`装饰器表示该方法是一个类方法,可以通过类本身访问,而不是通过实例。
通过这两个装饰器的组合,我们可以将`__doc__()`方法转换为一个可以通过`G.__doc__`访问的类属性。在这个方法中,我们使用字符串格式化来生成一个文档字符串,它包含类名的引号括起来的表示形式,并返回该字符串。
希望这能帮到你!如果还有其他问题,请随时问。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
class G:
@classmethod
@property
def __doc__(cls):
return f'A doc for {cls.__name__}'
这个不用语法糖的话,应该是怎么写的?@FishC 亦又 发表于 2024-04-12 17:46
class G:
@classmethod
@property
def ...
使用语法糖的目的是为了简化代码并提高可读性,所以将其转化为不使用语法糖的形式可能会显得有些繁琐。不过,你可以像下面这样来实现相同的功能:
class G:
def __doc__(self):
return f'A doc for {self.__class__.__name__}'
__doc__ = property(__doc__)
在上面的代码中,我们定义了一个名为`__doc__`的普通函数,并将其赋值给了`G`类的`__doc__`属性。然后,我们使用内置的`property()`函数将`__doc__`属性转换为一个可读的属性。
希望能够帮到你!如果还有其他问题,请随时提问。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
class G:
@classmethod
@property
def __doc__(cls):
return f'A doc for {cls.__name__}'
这个不用语法糖的话,把语法糖还原怎么写的?@FishC 亦又 发表于 2024-04-12 17:49
class G:
@classmethod
@property
def ...
要还原这段代码中的语法糖,可以将装饰器的写法改为常规的调用方式。
装饰器 `@classmethod` 可以改写成 `classmethod(函数名)`,装饰器 `@property` 可以改写成 `property(函数名)`。
所以,还原后的代码如下:
class G:
def __doc__(cls):
return f'A doc for {cls.__name__}'
__doc__ = property(__doc__)
__doc__ = classmethod(__doc__)
这样我们就还原了 `@classmethod` 和 `@property` 的装饰器写法。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 class ClassMethod:
'''Emulate PyClassMethod_Type() in Objects/funcobject.c'''
def __init__(self, f):
self.f = f
def __get__(self, obj, cls=None):
if cls is None:
cls = type(obj)
if hasattr(type(self.f), '__get__'):
return self.f.__get__(cls, cls)
return MethodType(self.f, cls)
hasattr()函数不是用于判断对象是否拥有某个属性吗?
那这里的 hasattr()判断的是'__get__'属性,还是'__get__'方法?
@FishC 亦又 发表于 2024-04-12 20:15
class ClassMethod:
'''Emulate PyClassMethod_ ...
`hasattr()`函数用于判断对象是否拥有某个属性或方法。在这段代码中,`hasattr(type(self.f), '__get__')`判断的是`self.f`所属类(即`type(self.f)`)是否拥有`__get__`方法。
在Python中,类和实例都可以有属性,而属性可以是数据属性或方法。当我们使用点语法访问、设置或删除属性时,实际上是对特殊方法`__getattribute__()`、`__setattr__()`和`__delattr__()`的调用。其中,`__getattribute__()`用于获取属性值,`__setattr__()`用于设置属性值,`__delattr__()`用于删除属性。
在这段代码中,`self.f`是一个函数对象,它是一个可调用对象,因此可以被当作方法来调用。`__get__()`方法是描述符协议中的一种特殊方法,用于处理属性访问。通过调用`self.f.__get__(cls, cls)`,我们可以将`self.f`绑定到类`cls`上,并返回绑定后的方法。
所以,`hasattr(type(self.f), '__get__')`的作用是判断`self.f`所属类是否实现了描述符协议中的`__get__()`方法。如果实现了,就使用`self.f.__get__(cls, cls)`进行属性访问;如果未实现,就使用`MethodType(self.f, cls)`进行属性访问。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页:
[1]