我想知道是否可以在子类中使用描述符的装饰器。
class Descriptor():
def __get__(self, instance_obj, objtype):
raise Exception('ouch.')
def decorate(self, f):
print('decorate', f)
return f
class A():
my_attr = Descriptor()
class B():
@my_attr.decorate
def foo(self):
print('hey, whatsup?')
# --> NameError: name 'my_attr' is not defined
Run Code Online (Sandbox Code Playgroud)
这当然是行不通的,因为my_attr在 的类定义中未定义B。
接下来我尝试了:
class B():
@A.my_attr.decorate
def foo(self):
print('hey, whatsup?')
# --> Exception: ouch.
Run Code Online (Sandbox Code Playgroud)
但是,此方法调用描述符__get__方法(其中instance_obj参数为None),因此会触发测试异常。要访问装饰器,可以检查是否instance_obj返回None描述符本身:
def __get__(self, instance_obj, objtype):
if instance_obj is None:
return self
raise Exception('avoid this')
# --> …Run Code Online (Sandbox Code Playgroud) 我试图了解描述符如何在python中工作。我了解的很大,但是在理解@staticmethod装饰器时遇到了问题。
我具体指的代码来自相应的python文档:https : //docs.python.org/3/howto/descriptor.html
class Function(object):
. . .
def __get__(self, obj, objtype=None):
"Simulate func_descr_get() in Objects/funcobject.c"
if obj is None:
return self
return types.MethodType(self, obj)
Run Code Online (Sandbox Code Playgroud)
class StaticMethod(object):
"Emulate PyStaticMethod_Type() in Objects/funcobject.c"
def __init__(self, f):
self.f = f
def __get__(self, obj, objtype=None):
return self.f
Run Code Online (Sandbox Code Playgroud)
我的问题是:self.f在最后一行中访问when时,它本身不会f被识别为描述符(因为每个函数都是非数据描述符),因此绑定到self,这是一个StaticMethod对象吗?
我从有效的Python项目31中获得以下示例:
from weakref import WeakKeyDictionary
class Grade(object):
def __init__(self):
self._values = WeakKeyDictionary()
def __get__(self, instance, instance_type):
if instance is None: return self
return self._values.get(instance, 0)
def __set__(self, instance, value):
if not (0 <= value <= 100):
raise ValueError('Grade must be between 0 and 100')
self._values[instance] = value
# Example 16
class Exam(object):
math_grade = Grade()
writing_grade = Grade()
science_grade = Grade()
first_exam = Exam()
first_exam.writing_grade = 82
second_exam = Exam()
second_exam.writing_grade = 75
print('First ', first_exam.writing_grade, 'is right')
print('Second', second_exam.writing_grade, …Run Code Online (Sandbox Code Playgroud) 我正在学习python中的描述符.我想编写一个非数据描述符,但是__get__当我调用classmethod时,具有描述符作为其类方法的类不会调用特殊方法.这是我的例子(没有__set__):
class D(object):
"The Descriptor"
def __init__(self, x = 1395):
self.x = x
def __get__(self, instance, owner):
print "getting", self.x
return self.x
class C(object):
d = D()
def __init__(self, d):
self.d = d
Run Code Online (Sandbox Code Playgroud)
以下是我称之为:
>>> c = C(4)
>>> c.d
4
Run Code Online (Sandbox Code Playgroud)
该__get__描述符类的就没有得到调用.但是当我也设置一个__set__描述符似乎被激活:
class D(object):
"The Descriptor"
def __init__(self, x = 1395):
self.x = x
def __get__(self, instance, owner):
print "getting", self.x
return self.x
def __set__(self, instance, value):
print "setting", self.x
self.x = …Run Code Online (Sandbox Code Playgroud) 我读的地方有关的事实,你可以有一个描述符有__set__和无__get__.
它是如何工作的?
它算作数据描述符吗?它是非数据描述符吗?
这是一个代码示例:
class Desc:
def __init__(self, name):
self.name = name
def __set__(self, inst, value):
inst.__dict__[self.name] = value
print("set", self.name)
class Test:
attr = Desc("attr")
>>>myinst = Test()
>>> myinst.attr = 1234
set attr
>>> myinst.attr
1234
>>> myinst.attr = 5678
set attr
>>> myinst.attr
5678
Run Code Online (Sandbox Code Playgroud) 我希望一个特定的函数可以作为类方法调用,并且当它在一个实例上调用时表现不同.
例如,如果我有一个class Thing,我想Thing.get_other_thing()工作,但也thing = Thing(); thing.get_other_thing()表现不同.
我认为覆盖get_other_thing初始化方法应该有效(见下文),但这看起来有点hacky.有没有更好的办法?
class Thing:
def __init__(self):
self.get_other_thing = self._get_other_thing_inst()
@classmethod
def get_other_thing(cls):
# do something...
def _get_other_thing_inst(self):
# do something else
Run Code Online (Sandbox Code Playgroud) 我想更好地理解描述符.
我不明白为什么在foo __get__方法中没有调用描述符方法.
据我理解描述符,__get__当我通过点运算符或我使用时访问对象属性时,总是调用该方法__getattribute__().
根据Python文档:
class RevealAccess(object):
def __init__(self, initval=None, name='var'):
self.val = initval
self.name = name
def __get__(self, obj, objtype):
print('Retrieving', self.name)
return self.val
def __set__(self, obj, val):
print('Updating', self.name)
self.val = val
class MyClass(object):
x = RevealAccess(10, 'var "x"')
y = 5
def foo(self):
self.z = RevealAccess(13, 'var "z"')
self.__getattribute__('z')
print(self.z)
m = MyClass()
m.foo()
m.z # no print
m.x # prints var x
Run Code Online (Sandbox Code Playgroud) 来自 Python数据模型文档:
object.__get__(self, instance, owner=None)调用以获取所有者类的属性(类属性访问)或该类的实例的属性(实例属性访问)。可选
owner参数是所有者类,而instance属性是通过其访问的实例,或者None是通过owner.此方法应返回计算出的属性值或引发
AttributeError异常。PEP 252 指定可以
__get__()使用一个或两个参数调用。Python 自己的内置描述符支持这个规范;但是,某些第三方工具可能具有需要两个参数的描述符。__getattribute__()无论是否需要,Python 自己的实现总是传入这两个参数。
object.__set__(self, instance, value)调用以将
instance所有者类的实例上的属性设置为新值 value。请注意,将描述符的种类添加
__set__()或__delete__()更改为“数据描述符”。有关更多详细信息,请参阅调用描述符。
object.__delete__(self, instance)调用以删除
instance所有者类的实例上的属性。
为什么__get__需要一段owner时间__set__而__delete__没有?
这是否意味着当描述符同时提供__get__和时__set__,
我的问题实际上是这个问题的一部分。
这是两个离散的对象:
class Field(object):
pass
class MyClass(object):
spam = Field()
eggs = Field()
potato = Field()
Run Code Online (Sandbox Code Playgroud)
对于任何Field对象,是否存在一种方法让该对象知道MyClass分配它的属性名称?
我知道我可以将参数传递给Field对象,potato = Field(name='potato')但是在我的实际情况下这将是混乱和繁琐的,所以我只是想知道是否有非手动方式做同样的事情.
谢谢!
以此代码为例:
class SomeClass():
def a_method(self):
pass
print(SomeClass.a_method is SomeClass.a_method) # Example 1: False
print(SomeClass.a_method == SomeClass.a_method) # Example 2: True
print(SomeClass().a_method is SomeClass().a_method) # Example 3: False
print(SomeClass().a_method == SomeClass().a_method) # Example 4: False
Run Code Online (Sandbox Code Playgroud)
main():请参阅注释中提到的结果的函数。*一般注意事项:当Class()有一个attribute包含例如str->时,@propery.setter一旦设置就会验证。
但是,当我将 a 存储dictionary在 中时Class.attribute,@property.setter如果我直接设置 a ,则 My 不起作用key : value
class CoinJar():
def __init__(self):
self._priceDict = {'current' : 0.0, 'high' : 0.0, 'low' : 0.0}
self.klines = {}
self.volume = {}
def __str__(self):
return f'\n\U0001F36A'
@property
def priceDict(self):
return self._priceDict
@priceDict.setter
def priceDict(self, priceDict):
print('setting price')
try:
newPrice = float(priceDict.get('current'))
except ValueError as e:
print(f'Input cannot be converted to float {e}')
# Exceptions …Run Code Online (Sandbox Code Playgroud) python ×11
descriptor ×4
python-2.7 ×2
attributes ×1
class ×1
datamodel ×1
dictionary ×1
function ×1
methods ×1
oop ×1
python-3.5 ×1
python-3.x ×1