关于实例的属性

时间:2019-09-06 11:26:35

标签: python python-3.x oop

class Empl():
    def __init__(self, first, last):
        self.f = first
        self.l = last
        # Just checking something
        self.full = self.f + ' ' + self.l

first = Empl('Mickey', 'Mouse')

first.f = "Ricky"

print(first.full)  # It prints Mickey Mouse

为什么first.f中的更改未反映在first.full上?

2 个答案:

答案 0 :(得分:0)

因为self.full仅在创建对象时设置一次。如果您更改self.f,则不会更新。

您需要一种可以在发生任何更改时更新full值的方法:

class empl():
    def __init__(self,fist,last):
        self.f=fist
        self.l=last
        #Just checking something
        self.full=self.f + ' ' + self.l

    def change_f(self, new_val):
        self.f = new_val
        # Make sure to update
        self.full=self.f + ' ' + self.l

first=empl('Micki','Mouse')

first.change_f("Ricky")

print(first.full) # Will now print Ricky Mouse 

答案 1 :(得分:0)

要使self.fullname依赖于self.fself.l,请将其设为属性

class Empl():
    def __init__(self, first, last):
        self.f = first
        self.l = last

    @property
    def fullname(self):
        return self.f + " " + self.l

现在self.fullname的值将使用 self.fself.l的当前值,而不是存储字符串 由(可能是过期的)名字和姓氏创建。

请注意,按原样,您不能直接更改fullname,只能分别更改名字和姓氏。这是一个功能。 (如何使fullname可分配超出了此答案的范围。)


表达式self.f + ' ' + self.l未链接到self.fself.l引用的对象;以图形方式,您从

开始
(1)
self.f ------>  "foo"
self.l ------>  "bar"

结尾
(2)
self.f ------>  "foo"
self.l ------>  "bar"
self.full --->  "foo bar"

不是

(3)
self.f ------>  "foo"  <----\
                  " "  <----+---self.full
self.l ------>  "bar"  <----/

self.full是一个独立的对象,不受self.fself.l的更改的影响。


即使上面是一个轻微谎言。任何特定的Python实现都可能在三个字符串对象之间共享内存,因为str对象是不可变的。您无法更改str引用的实际self.f来获得

(4)
self.f ------>  "fpo"  <----\
                  " "  <----+---self.full
self.l ------>  "bar"  <----/

,将foo更改为foo,同时影响self.fself.full。您只能更改self.f所指的内容,例如

(5)
          +--> "fpo"
          |
self.f ---+     "foo"  <----\
                  " "  <----+---self.full
self.l ------>  "bar"  <----/

但是,任何这样的内存共享都是 一个强制细节,而不是Python本身可见的东西。实际上,您只能“看到”(2),无论字符串"foo""bar"在内存中表示一次还是两次。