python:在类内实例化类与在类内实例化类与在类外实例化类之间的区别是什么?

本问题已经有最佳答案,请猛点这里访问。

在这个例子中,Goodbye和Farewell有什么区别吗?一个比另一个有什么优势吗?

1
2
3
4
5
6
7
8
9
10
11
12
13
class Hello(object):

    def hi(self):
        pass

class Goodbye(object):

    def __init__(self):
        self.hello = Hello()

class Farewell(object):

    hello = Hello()


考虑下面的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Hello(object):

    def hi(self):
        print("Hello")

class Goodbye(object):

    def __init__(self):
        self.hello = Hello()
        print("this is the Goodbye text")

class Farewell(object):

    hello = Hello()
    print("this is the Farewell text")

构造该类的对象时调用。因此,在创建一个goodbye()对象(类似于s = Goodbye())之前,您不会看到文本"this is the goodbye text"。但是,在运行包含Farewell类的python脚本时,您将看到"this is the Farewell text",但是在创建Farewell类的对象时,您将看不到"this is the Farewell text"。


是的。Goodbye类和Farewell类的区别在于Goodbye有一个实例成员hello,而Farewell类有一个类成员hello。如果你改变了属于Farewell对象的Hello类,那么所有的Farewell实例都会看到改变,所以你可以这样做:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
a = Goodbye()
b = Goodbye()

a.hello.member = 1 # monkey-patching the member
b.hello.member = 2

print(a.hello.member) # prints"1"
print(b.hello.member) # prints"2"

f = Farewell()
g = Farewell()

f.hello.member = 1
g.hello.member = 2

print(f.hello.member) # prints"2"!

这样做的原因是,正如您所定义的,Goodbye类的实例有自己的Hello对象实例,而Farewell类的所有实例共享同一个Hello对象。查看文档了解更多信息!

现在,其中一个是否比另一个拥有任何优势取决于实现。类成员有时会让用户感到困惑,因为他们可能希望类的不同实例独立于其他操作(例如,,可变类成员会破坏封装。)然而,从效率的角度来看,定义跨所有类的常量成员可能是有用的(确保以某种方式向用户说明这一点,比如将它们隐藏在下划线前缀或清晰的文档后面)。