python - 关于实例的属性
问题描述
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
?
解决方案
要self.fullname
依赖self.f
and self.l
,使其成为属性:
class Empl():
def __init__(self, first, last):
self.f = first
self.l = last
@property
def fullname(self):
return self.f + " " + self.l
现在,将使用andself.fullname
的当前值即时计算 的值,而不是存储从(可能过时的)名字和姓氏创建的字符串。self.f
self.l
请注意,您不能fullname
直接更改,只能单独更改名字和姓氏。这是一个特点。(如何使fullname
可分配超出了此答案的范围。)
该表达式self.f + ' ' + self.l
未链接到self.f
or引用的对象self.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.f
或的变化的影响self.l
。
即使是上面的,也是一个小小的谎言。任何特定的 Python 实现都可能在三个字符串对象之间共享内存,因为str
对象是不可变的。你不能改变实际str
的self.f
引用来获得类似的东西
(4)
self.f ------> "fpo" <----\
" " <----+---self.full
self.l ------> "bar" <----/
随着 的foo
变化foo
影响self.f
和self.full
。您只能更改self.f
所指的内容,例如
(5)
+--> "fpo"
|
self.f ---+ "foo" <----\
" " <----+---self.full
self.l ------> "bar" <----/
然而,任何这样的内存共享都只是一个实现细节,而不是 Python 本身可见的东西。实际上,您只能“看到”(2),字符串"foo"
和是否"bar"
在内存中表示一次或两次。
推荐阅读
- json - JsonResult 将日期和时间编码为 UTC ......如何避免这种情况?
- python - 如何枚举任意深度的 n 叉树中每个元素的路径
- autodesk-forge - 如何从 BIM 360“计划”文件夹访问文件的“标题”
- rsync - 使用 R-sync 在数据中心之间持续更改文件复制 100 GB 是个好主意吗?
- javascript - 添加选项以在 JavaScript 中选择字段
- reactjs - React-Native 中的自定义滚动选择器功能
- algorithm - 蒙特卡洛树搜索随机洗牌游戏
- unit-testing - ReferenceError:尝试测试 AsyncStorage 时未定义 __DEV__
- typescript - 使用泛型定义混合类型
- vscode-remote - 是否可以将 kerberos 身份验证与 Visual Studio Code Remote 一起使用?