标签:python 替代 接收 面向 类实例化 查找 one 使用 语法
__get__
, __set__
, __delete__
)这三个方法中的任意一个方法",那么我们称该属性为"描述符"class Foo(object):
def init(self, name, age):
self.name = name
self.age = age
foo = Foo("pizza", 18)
class Foo(object):
country = "China"
def __init__(self, name, age):
self.name = name
self.age = age
foo = Foo("pizza", 18)
print(foo.__dict__) # {‘name‘: ‘pizza‘, ‘age‘: 18}
print(type(foo).__dict__) # {‘__module__‘: ‘__main__‘, ‘country‘: ‘China‘, ‘__init__‘: <function Foo.__init__ at 0x103802488>, ‘__dict__‘: <attribute ‘__dict__‘ of ‘Foo‘ objects>, ‘__weakref__‘: <attribute ‘__weakref__‘ of ‘Foo‘ objects>, ‘__doc__‘: None}
foo.__dict__
, 如果print(foo.country)则会查找type(foo)既Foo.__dict__
。descr.__get__(self, obj, type=None) --> value
descr.__set__(self, obj, value) --> None
descr.__delete__(self, obj) --> None
class Bar(object):
def __get__(self, instance, owner):
print("__get__")
def __set__(self, instance, value):
print("__set__")
def __delete__(self, instance, value):
print("__delete__")
class Foo(object):
bar = Bar()
foo = Foo()
__get__
()和__set__
()这两个方法,那么我们认为该对象是一个Data Descriptor。如果只定义了__get__
()方法,那就是Non-data Descriptor,如下代码所示:class Bar(object):
def __get__(self, instance, owner):
print("get")
def __set__(self, instance, value):
print("__set__")
def __delete__(self, instance, value):
print("__delete__")
class Foo(object):
bar = Bar()
foo = Foo()
class Bar(object):
def __get__(self, instance, owner):
print("__get__")
class Foo(object):
bar = Bar()
foo = Foo()
__dict__
中有一个跟Data Descriptor同名的属性,那么,Data Descriptor会覆盖__dict__
的查找,如下代码所示:class Bar(object):
def __get__(self, instance, owner):
print("__get__")
def __set__(self, obj, value):
print("__set__")
class Foo(object):
bar = Bar()
def __init__(self, name, age):
self.name = name
self.age = age
self.bar = "bar"
foo = Foo("pizza", 18)
foo.bar # __get__
__get__
方法。因为,Data Descriptor会覆盖__dict__
的查找。__dict__
中有一个跟Non-data Descriptor同名的属性,那么,对象的__dict__
查找会覆盖Non-data Descriptor,如下代码所示:class Bar(object):
def __get__(self, instance, owner):
print("__get__")
class Foo(object):
bar = Bar()
def __init__(self, name, age):
self.name = name
self.age = age
self.bar = "bar"
foo = Foo("pizza", 18)
foo.bar # "bar"
__dict__
查找会覆盖Non-data Descriptor。class Foo(object):
def __init__(self, name):
self._name = name
@property
def name(self):
return self._name
foo = Foo("Pizza")
print(foo._name) # "Pizza"
print(foo.name) # "Pizza"
self._name
)。__init__
里面定义一个属性。class Foo(object):
def __init__(self, name):
self._name = name
@property
def stock(self):
return 100 + 100
foo = Foo("Pizza")
print(foo._name) # "Pizza"
print(foo.stock) # 200
class Foo(object):
def stock(self):
return 100 + 100
print(stock) # <function Foo.stock at 0x101a57048>
class Foo(object):
@property
def stock(self):
return 100 + 100
print(stock) # <property object at 0x103811c78>
<property object at 0x103811c78>
和<function Foo.stock at 0x101a57048>
,既,在stock方法上面加上@property之后,stock这个方法变为了property的对象,与第一个print(stock)的<function Foo.stock at 0x101a57048>
不同。class Foo(object):
def stock(self):
return 100 + 100
foo = Foo()
foo.stock
__get__, __set__, __delete__
;class Stock(object):
def __get__(self, instance, owner):
print("__get__")
return 100 + 100
class Foo(object):
stock = Stock()
foo = Foo()
foo.stock
__get__
, 然后显示200。那么,如果我们将stock变为类中的一个方法呢?如下代码所示:class Stock(object):
def __get__(self, instance, owner):
print("__get__")
return 100 + 100
class Foo(object):
def stock(self):
print("stock")
__get__
方法,然后获取其返回值,既,200。__get__
方法即可,如:stock = Stock(),但是,如何利用装饰器语法糖呢?我们知道,装饰器语法糖@Stock等价于stock = Stock(stock),因此,我们需要,在Stock这个类中定义一个__init__
方法,并定义一个形参来接收Stock类实例化时传入的stock函数,如下代码所示:class Stock(object):
def __init__(self, stock):
self.stock = stock
def __get__(self, instance, owner):
print("__get__")
return 100 + 100
class Foo(object):
@Stock # stock = Stock(stock)
def stock(self):
print("stock")
foo = Foo()
foo.stock
__get__
, 然后显示200。class Foo(object):
@property
def stock(self):
return 100 + 100
foo = Foo()
foo.stock
__get__
方法时,它接受三个参数,第一个self表示descriptor,下面我们,分别print第二个和第三个参数,看看它们分别表示什么:class Stock(object):
def __init__(self, stock):
self.stock = stock
def __get__(self, instance, owner):
print("__get__")
print("instance: ", instance)
print("owner:", owner)
return 100 + 100
class Foo(object):
@Stock
def stock(self):
print("stock")
foo = Foo()
foo.stock
__get__
instance: <__main__.Foo object at 0x106c2b9b0>
owner: <class ‘__main__.Foo‘>
200
__get__
方法中,调用stock呢?__get__
方法中调用,那么就进入死循环了,一直重复的执行__get__
方法。__init__
方法进行初始化,因此,此时我们只能通过如下代码示例中使用的方式,进行调用:class Stock(object):
def __init__(self, stock):
self.stock = stock
def __get__(self, instance, owner):
return self.stock(instance)
class Foo(object):
@Stock
def stock(self):
return 100 + 100
foo = Foo()
foo.stock
200
class myproperty(object):
def __init__(self, stock):
self.stock = stock
def __get__(self, instance, owner):
return self.stock(instance)
class Foo(object):
@myproperty
def stock(self):
return 100 + 100
foo = Foo()
foo.stock
标签:python 替代 接收 面向 类实例化 查找 one 使用 语法
原文地址:https://www.cnblogs.com/paulwhw/p/9445301.html