向Python对象添加新属性?

2024-09-30 10:30:56 发布

您现在位置:Python中文网/ 问答频道 /正文

作为OOPS的背景,看到下面来自link的代码看起来很奇怪

def f():
    f.beencalled = True
    return 0

我的问题:

(一) 根据上面的代码, f是指向class 'function'的对象f的引用变量吗?在

(二) 我们将一个新的属性beencalled添加到一个对象f,所以现在'function'类没有定义这个属性{},我们说对象{}是{}的对象?有道理吗?在


Tags: 对象代码truereturn属性定义deflink
3条回答

另一方面,您可以为自定义类更改此行为。在

class FooBar(object):
    __slots__ = ["foo","bar","baz"]
    # if you don't define __slots__, you can add attr to the object as needed
    # if you do, the object can only contain those attributes.
    def __init__(self,foo=None,bar=None,baz=None):
        self.foo = foo
        self.bar = bar
        self.baz = baz
    def __str__(self):
        return "I'm a FooBar with id {0} with foo: {1.foo}, bar: {1.bar}, baz: {1.baz}".format(id(self),self)

>>> a = FooBar("a","B","CCC")
>>> print(a)
I'm a FooBar with id 47260256 with foo: a, bar: B, baz: CCC
>>> a.spam = "eggs"
Traceback (most recent call last):
  File "<pyshell#13>", line 1, in <module>
    a.spam = "eggs"
AttributeError: 'FooBar' object has no attribute 'spam'

或者,不定义__slots__

^{pr2}$

1)是:

>>> def f():
        print(type(f))

>>> f()
>>> <class 'function'>

2)function类没有新属性,但对象f有。向对象添加或删除属性不会影响该类的其他对象将具有哪些属性:

^{pr2}$ Python在Python中比java或C++更灵活。对象可以具有未在其类中定义的属性,甚至可能缺少在其类中定义的属性!看看这个:

>>> class A:
def __init__(self, a):
    self.var = a


>>> obj = A(7)
>>> del obj.var #deletes the var attribute from obj, does not change the A class
>>> obj.var
Traceback (most recent call last):
  File "<pyshell#28>", line 1, in <module>
    obj.var
AttributeError: 'A' object has no attribute 'var'

>>> obj2 = A(6)
>>> obj2.var #obj2 is a new object, so the fact we deleted var from obj doesn't affect it
6 

编辑:经过一段时间的搜索,我找到了一个解释为什么选择这个行为(source):

To implement user-defined objects, I settled on the simplest possible design; a scheme where objects were represented by a new kind of built-in object that stored a class reference pointing to a "class object" shared by all instances of the same class, and a dictionary, dubbed the "instance dictionary", that contained the instance variables.

In this implementation, the instance dictionary would contain the instance variables of each individual object whereas the class object would contain stuff shared between all instances of the same class in particular, methods. In implementing class objects, I again chose the simplest possible design; the set of methods of a class were stored in a dictionary whose keys are the method names. This, I dubbed the class dictionary. To support inheritance, class objects would additionally store a reference to the class objects corresponding to the base classes. At the time, I was fairly naïve about classes, but I knew about multiple inheritance, which had recently been added to C++. I decided that as long as I was going to support inheritance, I might as well support a simple-minded version of multiple inheritance. Thus, every class object could have one or more base classes.

In this implementation, the underlying mechanics of working with objects are actually very simple. Whenever changes are made to instance or class variables, those changes are simply reflected in the underlying dictionary object. For example, setting an instance variable on an instance updates its local instance dictionary. Likewise, when looking up the value of a instance variable of an object, one merely checks its instance dictionary for the existence of that variable. If the variable is not found there, things become a little more interesting. In that case, lookups are performed in the class dictionary and then in the class dictionaries of each of the base classes.

f()types.FunctionType的一个实例中,并且实例可以有自己的属性。在

向实例添加属性不会影响其类,除非您重写了该类的__setattr__方法并在其中做了坏事。在

>>> import types
>>> def func(): pass
>>> isinstance(func, types.FunctionType)
True

相关问题 更多 >

    热门问题