Python 如何从uuu init_uuu中删除在uuu init_uuu外部定义的类属性?

Python 如何从uuu init_uuu中删除在uuu init_uuu外部定义的类属性?,python,attributes,Python,Attributes,classFoo: class Foo(): def __init__(self): del self.foo def foo(self): pass 实例化raisesAttributeError:Foo实例没有属性“Foo”。从object(class Foo(object))派生Foo)raisesAttributeError:'Foo'对象属性'Foo'是只读的。使用delattr(self,“foo”)也没有帮助 执行以下操作也不会从

class
Foo

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

    def foo(self):
        pass
实例化
raise
s
AttributeError:Foo实例没有属性“Foo”
。从
object
class Foo(object)
)派生
Foo
raise
s
AttributeError:'Foo'对象属性'Foo'是只读的
。使用
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 Foo():
定义初始化(自):
self.foo=None
del self.foo
def foo(self):
通过
>>>Foo().Foo
目标:

我基本上希望完全删除/或使给定
类的实例中的某些属性不可访问,前提是满足某些条件


有什么建议吗?

问题是,您试图删除的是一个方法,而方法不是存储在实例上,而是存储在类上

因此,您的实例
Foo()
实际上没有属性
Foo
。执行
Foo().Foo
时,它会在
Foo
上找到
Foo
。因此,在
self
上没有要删除的内容,因为该属性不在
self

如果类定义了一个方法(或任何类属性)
foo
,则无法从单个实例中删除它。您所能做的最好是使用一些
\uuu getattribute\uuu
黑客程序使其引发异常。但是,这会对每个
Foo
实例上的每个属性访问产生性能影响


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

问题是您试图删除的是一个方法,而方法不是存储在实例上,而是存储在类上

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()
实际上没有属性
Foo
。执行
Foo().Foo
时,它会在
Foo
上找到
Foo
。因此,在
self
上没有要删除的内容,因为该属性不在
self

如果类定义了一个方法(或任何类属性)
foo
,则无法从单个实例中删除它。您所能做的最好是使用一些
\uuu getattribute\uuu
黑客程序使其引发异常。但是,这会对每个
Foo
实例上的每个属性访问产生性能影响

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

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
的子类,并在实例化之前选择正确的类

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
实例,然后在实例中查找名称
Foo
。该实例没有
foo
属性,因此查找返回到实例的类,即
foo
。这就是绑定在类块中的名称的工作方式;它们在类对象上创建属性,并且仅通过此查找回退机制间接影响实例。这正是普通方法调用的工作原理——对于一个有10个方法和1000个实例的类,我们不需要10000个方法对象

获取实例属性的唯一方法是,如果某些代码在引用实例后直接将其分配给实例,如
\uuu init\uuu
中典型的
self.name=something
模式

因此,无法使用
del
从一个实例中去除
foo
;您可以
del Foo.Foo
将其从类中删除,但这会影响所有实例。在初始化一个特定实例的
\uuuuu init\uuuuu
方法中加入这一点没有任何意义


您可以通过在
self
上定义
foo
来屏蔽它;然后,一个优先,它可以根据不同的实例而变化(但是如果你曾经
del
它,那么
foo
开始再次返回类
foo
。或者你可以使用像
\uuuu getattribute\uuuu
这样的通用属性访问钩子来做一些检查,有时表现得好像
foo
不存在。或者你可以完全摆脱
foo
作为类属性,一个d当您确实需要时,将其添加到每个实例中,而不是在不需要时将其删除。

foo
不是
foo
实例的属性,而是
foo
类对象的属性

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

获取实例属性的唯一方法是,如果某些代码在引用实例后直接将其分配给实例,如
\uuu init\uuu
中典型的
self.name=something
模式

因此,无法使用
del
仅从一个实例中删除
foo
;您可以
del foo.foo
将其从类中删除,但这会影响所有实例。这并不会造成任何问题