0

class Foo

class Foo():
    def __init__(self):
        del self.foo

    def foo(self):
        pass

当实例化raises时AttributeError: Foo instance has no attribute 'foo'。源自( ) s 。Foo_ 使用也无济于事。objectclass Foo(object)raiseAttributeError: 'Foo' object attribute 'foo' is read-onlydelattr(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如果满足某些条件,我基本上想从给定的实例中完全删除/或使某些属性无法访问。

有什么建议么?

4

4 回答 4

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()
于 2013-07-23T08:37:08.813 回答
1

问题是您要删除的是一个方法,并且方法没有存储在实例中,它们存储在类中。

所以你的实例Foo()并没有真正的属性foo。当你这样做时Foo().foo,它会找到fooon Foo。所以没有什么可以删除 on self,因为属性不在 on self

如果类定义了方法(或任何类属性)foo,则无法从单个实例中删除它。您能做的最好的事情就是使用一些__getattribute__hackery 使其引发异常。Foo但是,这会给每个实例上的每个属性访问带来性能损失。

为什么你觉得有必要这样做?

于 2013-07-23T08:32:46.210 回答
0

foo不是Foo实例的属性,它是Foo 对象的属性。

当您使用Foo().foo时,该行会创建一个新Foo实例,然后在实例中查找名称foo。实例没有foo属性,因此查找回退到实例的类,即Foo. 这就是绑定在类块中的名称的工作方式;它们在类对象上创建属性,并且仅通过这种查找回退机制间接影响实例。这正是普通方法调用的工作方式——对于一个有 10 个方法和 1000 个实例的类,我们不想要 10,000 个方法对象!

在实例上获得属性的唯一方法是,如果某些代码在实例具有对实例的引用后直接在实例上分配它,self.name = something__init__.

所以没有办法从一个实例del中删除;foo您可以del Foo.foo将其从类中删除,但这会影响所有实例。放入__init__初始化一个特定实例的方法中没有任何意义。

您可以通过定义fooon来掩盖它self;然后那个优先,它可能因实例而异(但如果你曾经del开始foo再次回到类foo。或者你可以使用通用属性访问钩子,比如__getattribute__做一些检查,有时表现得好像foo没有存在。或者您可以完全摆脱foo作为类属性,并在需要时将其添加到每个实例中,而不是在不需要时将其删除

于 2013-07-23T08:40:02.890 回答
0

你可以试试这个:

class Foo(object):
 def __init__(self):
  setattr(self,"foo", None)
 def foo(self):
  pass

>>> Foo().foo
>>>
于 2013-07-23T08:40:22.517 回答