class
Foo
:
class Foo():
def __init__(self):
del self.foo
def foo(self):
pass
实例化raise
s AttributeError: Foo instance has no attribute 'foo'
时。从Foo
(object
)class Foo(object)
s raise
中获取AttributeError: 'Foo' object attribute 'foo' is read-only
。使用delattr(self, "foo")
也无济于事。
执行以下操作不会删除Foo
实例中的属性:
class Foo():
def __init__(self):
self.foo = None
del self.foo
def foo(self):
pass
>>> Foo().foo
<bound method Foo.foo of <__main__.Foo instance at 0x00000000042EA248>>
目的:
我基本上想要从给定class
的实例中完全删除/或使某些属性无法访问,只要满足某些条件。
有什么建议吗?
答案 0 :(得分:2)
class Foo(object):
def __init__(self):
self.foo = None # This masks the foo method on the instance `self`
def foo(self):
pass
foo = Foo()
print(foo.foo)
# None
print(foo.foo())
# TypeError: 'NoneType' object is not callable
但是,你确定要这个设计吗?也许改为定义Foo
的子类,并在实例化之前选择正确的类 ...
class Base(object):
def common_method(self): pass
class Foo(Base):
def foo(self): pass
class AltFoo(Base):
def alt(self): pass
def make_foo():
if somecondition:
return Foo()
eles:
return AltFoo()
答案 1 :(得分:1)
问题是你要删除的是一个方法,方法没有存储在实例上,它们存储在类中。
因此,您的实例Foo()
实际上没有属性foo
。执行Foo().foo
后,它会在foo
上找到Foo
。因此self
上没有要删除的内容,因为该属性不在self
上。
如果类定义了一个方法(或任何类属性)foo
,则无法从单个实例中删除它。你能做的最好的事情就是使用一些__getattribute__
hackery来引发异常。但是,这会对每个Foo
实例上的每个属性访问产生性能影响。
为什么你觉得有必要这样做?
答案 2 :(得分:0)
foo
不是Foo
个实例的属性,而是Foo
类对象的属性。
当您使用Foo().foo
时,该行会创建一个新的Foo
实例,然后在实例中查找名称foo
。该实例没有foo
属性,因此查找将回退到实例的类Foo
。这就是类块中绑定的名称的工作方式;它们在类对象上创建属性,并且仅通过此查找回退机制间接影响实例。这正是普通方法调用的工作原理 - 对于一个包含10个方法和一千个实例的类,我们不需要10,000个方法对象!
方式,您将获得实例上的属性,如果某些代码在实例引用后直接在实例上为分配,就像在self.name = something
中的典型__init__
模式。
因此,无法使用del
从一个实例中删除foo
;您可以del Foo.foo
将其从类中删除,但这会影响所有实例。对于初始化一个特定实例的__init__
方法而言,这并不合理。
您可以通过在foo
上定义self
来屏蔽它;那么一个优先级并且它可以因实例而异(但是如果你del
那么它foo
再次开始回到类foo
。或者你可以使用通用属性访问像__getattribute__
这样的钩子进行一些检查,有时表现得好像foo
不存在。或者你可以完全摆脱foo
作为类属性,并将其添加到每个实例当你做想要它而不是删除它时。
答案 3 :(得分:0)
你可以试试这个:
class Foo(object):
def __init__(self):
setattr(self,"foo", None)
def foo(self):
pass
>>> Foo().foo
>>>