既然 self 指的是实例,那么在__init__()中对 self 重新赋值,比如, self = 4.21 ,然后对实例对象进行打印,结果应该打印出 4.21 这个值,可实验结果却不是。
class A(int):
def __init__(self, t):
self = 4.21
a = A(34)
print a # a = 34,而不是 4.21
求解。
1
hitmanx 2016-06-16 15:16:38 +08:00
python 我也是学习中,说错请见谅。
1. self 相当与其它语言里的 this 指针吧, self=4.21 本来就是有问题的语句. 2. 4.21 本来就不是浮点数,你注释里写的期待值是 4.21 肯定是不对的,当成功时应该期待的是 4 而不是 4.21 3. 你需要显示给父类,也就是这里的 int 类进行初始化 4. int 在 python 里是 immutable type,在这种情况下初始化父类时需要用__new__而不是__init__ 以上这些你稍微拿关键字搜一下就能出来了: http://stackoverflow.com/questions/3238350/subclassing-int-in-python http://stackoverflow.com/questions/2673651/inheritance-from-str-or-int # int is immutable so you can't modify it after they are created, use __new__ instead class TestClass(int): def __new__(cls, *args, **kwargs): return super(TestClass, cls).__new__(cls, 4.21) print TestClass(34) |
2
SErHo 2016-06-16 15:16:59 +08:00
对 self 赋值的时候,其实是创建了一个新的局部变量,比如执行以下代码:
>>> class A(int): ... def __init__(self): ... print id(self) ... self = 42 ... print self ... print id(self) ... ... ... >>> a = A() 4543469472 42 140376639849864 给个链接: http://stackoverflow.com/questions/1015592/why-is-self-in-python-objects-immutable |
3
sudo987 OP 谢谢二位仁兄的回答,可能是我描述不清,是这样的,我们都知道__init__()是实例创建后执行的第一个方法,并且 python 没有赋值时的变量审查,所以我觉得在__init__()里对 self 赋什么值都是可以的,所以我想在__init__()对 self 进行赋值,让 self 变成一个完全不同的东西,诸如从 int 编程 float ,我觉得应该是可以的,但是结果却不是这样,求解。
|
5
sudo987 OP @SErHo
``` class A(int): pass a = A(45) print a # 45 class B(int): def __init__(self, t): self = 45 b = B(2) print b # 2 而不是 45 ``` |
7
sudo987 OP @SErHo 谢谢提供链接,链接里给的例子很到位,”__new__()是真正的构造器,__init__()只是个初始化器“,这个说的比较好,可是具体“为什么”没有给出,而且您给出的通过 id()判断 self 似乎和我的问题关系不大,重新给 self 赋值,相当于改变 self 指针的指向,从 A 实例变成指向 42 ,可是,不管在不在__init__()做操作, id(self)前后的值肯定是不一样的。我不明白的是既然可以对 self 动态赋值,为什么不能改变 self 的指向(在 new 里面肯定可以,因为他是生成实例的地方),求解。
|
8
srlp 2016-06-16 16:07:10 +08:00
self 已经成为同名局部变量。
|
9
srlp 2016-06-16 16:08:53 +08:00
没有办法改变 self 的“指向”,因为此处没有类似 c 语言里面类似 *ptr 那种 dereference 操作符。
|
10
21grams 2016-06-16 16:29:02 +08:00 via Android
self 也能乱改的?
|
12
mulog 2016-06-16 16:37:42 +08:00
|
13
sxmman 2016-06-16 16:41:34 +08:00
@sudo987 为什么是 new 里面创建实例,因为涉及到元类 metaclass 的概念,任何对象的都是从 type 继承过来的,如果申明某一个类为子类的 metaclass ,且在父类中重载 __new__方法的话,可以控制实例的生成,但是其实还是 super(Parent, cls).__new__(cls)得到的,所以任何类的 parent 其实都是 type 。
至于为什么 init 中改变 self 本身无效,我猜是这样的,传入的 self 是一个变量,他的值就是实例的指针,也就是 c 中的**p ,如果改变他的值,并没有把 *p 的值修改,所以修改无效。 |
14
cxyfreedom 2016-06-16 16:55:33 +08:00
你__init__中的 self 只是同名的变量,你并没有对实际的对象进行改变。本身对象的 self 应该不能修改吧
|
15
xiaolee59 2016-06-16 17:34:48 +08:00
所有在局部作用域内的重新赋值(其实是名字和值的绑定)都会使解释器将该名字看做是当前局部作用域内的局部变量,你给 self 赋值,“ self ”这个名字在__init__内就绑定到了 4.21 这个值,然而, self 的有效生命周期仅仅存在于__init__内,对传进来的对象无影响。
|
16
sudo987 OP @sxmman 多谢回复,纠正一下,任何类都是一个 type 这个准确,可任何对象都是从 type 继承来的,这个不对, object 是继承链的顶端,连 type 都是它的子类。
|
17
sudo987 OP |
18
RTNelo 2016-06-16 21:28:13 +08:00
文档中的解释:
https://docs.python.org/2/reference/datamodel.html#the-standard-type-hierarchy 注意 Callable types 中 User-defined methods 的说明。 另外建议把 Data Model 这一章看完。 |
19
haoc 2016-06-17 05:55:01 +08:00
我的理解是: self 是 instance 的 reference 。在__init__這個 scope 里你對 self 進行賦值,所以在__init__中有一個 local 的 self 。所以最後的結果是 instance 本身沒有被改變。
|