![](/img/trans.png)
[英]Python class: How to check whether an attribute is defined inside __init__ or outside __init__
[英]How to delete class attributes defined outside the __init__ from within __init__?
Foo
class
:
class Foo():
def __init__(self):
del self.foo
def foo(self):
pass
实例化时, raise
s AttributeError: Foo instance has no attribute 'foo'
。 从object
( class Foo(object)
)派生Foo
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
的实例中完全删除/或使某些属性无法访问。
有什么建议么?
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()
问题是您要删除的是一个方法,而方法没有存储在实例上,而是存储在类上。
因此,您的实例Foo()
实际上没有属性foo
。 当您执行Foo().foo
,它将在Foo
上找到foo
。 因此,关于self
,没有什么可删除的,因为属性不在self
。
如果类定义了方法(或任何类属性) foo
,则无法从单个实例中将其删除。 最好的办法是使用一些__getattribute__
黑客程序使其引发异常。 但是,这会给每个Foo
实例上的每个属性访问带来性能Foo
。
为什么您觉得需要这样做?
foo
不是Foo
实例的属性,而是Foo
类对象的属性。
当您使用Foo().foo
,该行将创建一个新的Foo
实例,然后在该实例中查找名称foo
。 该实例没有foo
属性,因此查找回溯到该实例的类Foo
。 这就是绑定在类块中的名称的工作方式。 它们在类对象上创建属性,并且仅通过此查找回退机制间接影响实例。 这就是普通方法调用的工作方式-对于具有10个方法和1000个实例的类,我们不需要10,000个方法对象!
在实例上获取属性的唯一方法是,如果某些代码在引用实例后直接在实例上分配该属性,如典型的self.name = something
__init__
self.name = something
模式。
因此,无法使用del
从一个实例中摆脱foo
。 您可以del Foo.foo
从类del Foo.foo
其删除,但这会影响所有实例。 在初始化一个特定实例时,放入__init__
方法没有任何意义。
您可以通过在self
上定义foo
来掩盖它; 那么该实例将具有较高的优先级,并且实例之间的实例可能会有所不同(但是,如果您del
它,则foo
将再次回到foo
类。或者您可以使用__getattribute__
之类的通用属性访问钩子进行一些检查,有时还可以充当如果foo
不存在,或者您可以完全放弃foo
作为类属性,并在需要时将其添加到每个实例中,而不要在不存在时将其删除。
您可以尝试以下方法:
class Foo(object):
def __init__(self):
setattr(self,"foo", None)
def foo(self):
pass
>>> Foo().foo
>>>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.