Python中的旧样式和新样式类有什么区别?我什么时候应该使用其中一种?
我试图理解上的差异之间__getattr__和__getattribute__,但是,我在它失败.
Stack Overflow问题的答案vs 之间的差异__getattr____getattribute__说:
__getattribute__在查看对象的实际属性之前调用,因此正确实现可能很棘手.您最终可以轻松地进行无限递归.
我完全不知道这意味着什么.
然后继续说:
你几乎肯定想要
__getattr__.
为什么?
我读到如果__getattribute__失败,__getattr__就会被调用.那么为什么有两种不同的方法做同样的事情呢?如果我的代码实现了新的样式类,我应该使用什么?
我正在寻找一些代码示例来清除这个问题.我已经用Google搜索了我的能力,但我找到的答案并没有彻底讨论这个问题.
如果有任何文档,我准备阅读.
使用python属性,我可以这样做
obj.y
Run Code Online (Sandbox Code Playgroud)
调用函数而不是仅返回值.
有没有办法用模块做到这一点?我有一个我想要的案例
module.y
Run Code Online (Sandbox Code Playgroud)
调用函数,而不是只返回存储在那里的值.
__get__()和__getattr__()Python有什么区别?我来自PHP背景,只有__get().我什么时候应该使用哪个功能?
我一直试图解决这个问题.我看到很多的问题,如这一次,问的区别__getattr__()和__getattribute__(),虽然.
在特定情况下,选择在给定类中实现哪些内容的一般经验法则是什么?
我已经阅读了文档,因此理解它们之间的区别.相反,我正在寻找关于如何最好地将他们的使用集成到我的工作流程中的指导,方法是更好地注意到使用它们的更微妙的机会,以及何时使用它们.那种事.有问题的方法是(据我所知):
## fallback
__getattr__
__setattr__
__delattr__
Run Code Online (Sandbox Code Playgroud)
## full control
__getattribute__
##(no __setattribute__ ? What's the deal there?)
Run Code Online (Sandbox Code Playgroud)
## (the descriptor protocol)
__get__
__set__
__delete__
Run Code Online (Sandbox Code Playgroud) 概述:
class Inner(object):
def __init__(self, x):
self.x = x
class Outer(object):
def __init__(self, z):
self.inner = Inner(z)
o = Outer(10)
Run Code Online (Sandbox Code Playgroud)
现在,我希望Outer对象的行为透明 - 任何设置的属性o都应该设置为o.inner,同样用于读取:o.something应该返回,实际上,应该返回的值o.inner.sommething.有点像代理或中继.
__getattr__对于Outer看似简单&作品:
def __getattr__(self, item):
return getattr(self, item)
Run Code Online (Sandbox Code Playgroud)
我该怎么处理__setattr__?我无法想出任何不会导致递归错误的事情,让我讨厌自己.
或者概念本身是否存在缺陷?
(我尝试的另一种方法是创建Outer一个子类Inner- 这在现在并不真正美观@classmethods,更不用说IDE会在那些内部迷失 - 无法解决某些属性.让我们暂时离开,也许吧?)
Python为instance/class属性提供了许多可能性,例如:
class A(object):
def __init__(self):
self.foo = "hello"
a = A()
Run Code Online (Sandbox Code Playgroud)
有很多方法可以访问/更改以下值self.foo:
a.fooa.__dict__['foo']a.__get__和a.__set__,当然有两个是预先定义的方法.a.__getattribute____getattr__ 和 __setattr__在阅读源代码时,我总是迷失在他们最终的访问顺序之下?当我使用时a.foo,我如何知道实际调用哪个方法/属性?
是否可以使用已实例化的超类在Python中进行子类化?
我不完全知道如何提出问题,所以让我举个例子。假设我有一个Rectangle类,并且我想构建另一个类ColoredRectangle。但我不希望每个ColoredRectangle相同的维度成为自己的新维度Rectangle。因此,当我启动时,ColoredRectangle我将其传递给已实例化的对象Rectangle。
即,我想要
r = Rectangle([1,2])
r_red = ColoredRectangle(r, "red")
r_blue = ColoredRectangle(r, "blue")
Run Code Online (Sandbox Code Playgroud)
但是现在r_red,r_blue应该能够获取所有矩形方法和属性。例如,假设Rectangle有一个area()属性。
r.area
2
r_red.area
2
Run Code Online (Sandbox Code Playgroud)
r_red并r_blue应“指向”相同Rectangle。我知道我可以这样写:
class ColoredRectangle(Rectangle):
def __init__(self, rectangle, color):
self.color = color
self.rectangle = rectangle
Run Code Online (Sandbox Code Playgroud)
但是那我得写
r_red.rectangle.area
Run Code Online (Sandbox Code Playgroud)
这很丑。
我理解在python中,无论何时访问类/实例变量,它都会调用__getattribute__方法来获取结果.但是我也可以obj.__dict__['x']直接使用,得到我想要的东西.
我有点困惑有什么区别?当我使用时getattr(obj, name),是在呼叫__getattribute__还是在obj.__dict__[name]内部?
提前致谢.
我正在尝试更改Django模型的行为,以允许我直接从父级访问外键的属性,例如
cache.part_number
vs
cache.product.part_number
Run Code Online (Sandbox Code Playgroud)
我尝试重写该__getattr__方法如下,但当我尝试访问外键的属性时,我收到一个递归错误
class Product(models.Model):
part_number = models.CharField(max_length=10)
...
class Cache(models.Model):
product = models.ForeignKey(Product)
...
def __getattr__(self, name):
value = getattr(self.product, name, None)
if value:
return value
else:
raise AttributeError
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
python ×10
class ×4
attributes ×2
oop ×2
django ×1
getattr ×1
getattribute ×1
inheritance ×1
php ×1
properties ×1
python-3.x ×1
subclass ×1
types ×1