关于id类型对象的某些东西str(在python 2.7中)让我很困惑.该str类型是不变的,所以我希望,一旦它被创建,它将始终具有相同的id.我相信我不会这么说自己,所以我会发布一个输入和输出序列的例子.
>>> id('so')
140614155123888
>>> id('so')
140614155123848
>>> id('so')
140614155123808
Run Code Online (Sandbox Code Playgroud)
所以同时,它一直在变化.但是,在指向该字符串的变量之后,事情会发生变化:
>>> so = 'so'
>>> id('so')
140614155123728
>>> so = 'so'
>>> id(so)
140614155123728
>>> not_so = 'so'
>>> id(not_so)
140614155123728
Run Code Online (Sandbox Code Playgroud)
因此,一旦变量保存该值,它就会冻结id.的确,在del so和之后del not_so,id('so')开始的输出再次改变.
这是不相同的行为与(小)整数.
我知道不变性和拥有相同之间没有真正的联系id; 仍然,我试图弄清楚这种行为的来源.我相信那些熟悉python内部的人会比我更少惊讶,所以我试图达到同样的目的......
尝试使用不同的字符串会产生不同的结果......
>>> id('hello')
139978087896384
>>> id('hello')
139978087896384
>>> id('hello')
139978087896384
Run Code Online (Sandbox Code Playgroud)
现在它是平等的......
我以为is操作员检查对象id的相等性.但它似乎并非如此:
>>> class A(object):
... def f(): return 1
... def g(): return 2
...
>>> a = A()
>>> a.f is a.g
False
>>> id(a.f) == id(a.g)
True
Run Code Online (Sandbox Code Playgroud) 首先,我理解一般来说装饰工作是如何工作的.而且我知道@staticmethod在签名中剥离实例参数
class C(object):
@staticmethod
def foo():
print 'foo'
C.foo //<function foo at 0x10efd4050>
C().foo //<function foo at 0x10efd4050>
Run Code Online (Sandbox Code Playgroud)
有效.
但是,我不明白如何staticmethod实现这一点的源代码.
在我看来,该包装方法时foo的staticmethod,实例staticmethod被实例化,那么一些神奇的发生,使C.foo()合法的.
那么......那些魔法会发生什么?做了staticmethod什么?
我知道关于SO的巨大话题,staticmethods但没有一个能解决我的疑虑.但也许我没有点击魔术关键词.如果是的话,请告诉我.
对于寻找staticmethod源代码的人,请参阅https://hg.python.org/cpython/file/c6880edaf6f3/Objects/funcobject.c
python static-methods decorator python-internals python-decorators
Python 2.7中的代码结果让我感到矛盾.该is运营商应该与对象的身份工作,所以是id.但是当我查看用户定义的方法时,他们的结果会有所不同.这是为什么?
py-mach >>class Hello(object):
... def hello():
... pass
...
py-mach >>Hello.hello is Hello.hello
False
py-mach >>id(Hello.hello) - id(Hello.hello)
0
Run Code Online (Sandbox Code Playgroud)
我从Python数据模型的描述中发现以下摘录有些用处.但它并没有真正使一切清楚.id如果每次重新构造用户定义的方法对象,为什么函数返回相同的整数?
获取类的属性(可能通过该类的实例),如果该属性是用户定义的函数对象,未绑定的用户定义的方法对象或类方法对象,则可以创建用户定义的方法对象.当属性是用户定义的方法对象时,仅当从中检索它的类与存储在原始方法对象中的类相同或派生类时,才会创建新的方法对象; 否则,原始方法对象按原样使用.
在Python 2.7.9中,当我将未绑定方法分配给新属性并按is语句进行比较时,结果为False:
In [1]: class A(object):
...: def a(self):
...: pass
...:
In [2]: A._a = A.a
In [3]: print A.a, A._a
<unbound method A.a> <unbound method A.a>
In [4]: print id(A.a), id(A._a)
4499595904 4499595904
In [5]: A.a is A._a
Out[5]: False
Run Code Online (Sandbox Code Playgroud)
这是非常反直觉的,我找不到任何参考或文档来解释这种行为.更重要的是,当我在Python 3.4.2中测试相同的代码时,结果变成了True.我猜这是Python 2.7中的一个错误,但在Python 3中得到修复,任何人都可以帮我找到发生这种情况的真正原因吗?
在下面的代码中,我不明白为什么useless_func它属于两个不同的对象时具有相同的id?
class parent(object):
@classmethod
def a_class_method(cls):
print "in class method %s" % cls
@staticmethod
def a_static_method():
print "static method"
def useless_func(self):
pass
p1, p2 = parent(),parent()
id(p1) == id(p2) // False
id(p1.useless_func) == id(p2.useless_func) // True
Run Code Online (Sandbox Code Playgroud) 码:
class Foo(object):
pass
foo = Foo()
foo.__init__ == foo.__init__ #return true
foo.__init__ is foo.__init__ #return false
Run Code Online (Sandbox Code Playgroud)
我能理解foo.__init__ == foo.__init__回报True.为何foo.__init__ is foo.__init__回归False?
tl; dr Python重用ID吗?两个具有非重叠生命期的对象获得相同ID的可能性有多大?
背景:
我一直在研究一个复杂的项目,纯粹用Python 3编写.我一直在看测试中的一些问题,并花了很多时间寻找根本原因.经过一些分析后,我怀疑当测试作为一个整体运行时(它由一个专门的调度程序编排并运行),它会重用一些模拟方法,而不是用原始方法实现新对象.检查翻译是否重复使用我id().
问题:
id()通常可以工作并显示对象标识符,并让我告诉我的调用何时创建新实例而不重用.但是如果两个对象相同的话,会发生什么?文件说:
返回对象的"标识".这是一个整数,在该生命周期内保证该对象是唯一且恒定的.具有非重叠寿命的两个对象可以具有相同的
id()值.
问题:
解释器id()什么时候可以重用值?是在它随机选择相同的内存区域时吗?如果它只是随机的,似乎极不可能,但它仍然无法保证.
有没有其他方法来检查我实际引用的对象是什么?我遇到了一个我有对象的情况,它有一个模拟的方法.该对象不再使用,垃圾收集器将其销毁.我创建相同类的新对象后,就得到了一个新的id(),但该方法得到了相同的ID,当它被嘲笑为,它实际上是只是一个模拟.
有没有办法强制Python销毁给定的对象实例?从阅读中我看来没有,并且当它看不到对象的引用时它取决于垃圾收集器,但我认为无论如何都值得问.
我可以id()在实践中依赖对象及其独特性多少?例如:
id(a) == id(b)意味着a is b反之亦然?对面怎么样?id以后要使用的某个地方(例如进入某个注册表而不是对象本身)有多安全?(作为对Canonicals for Python的响应而写成的规范:具有相同id()的对象是相同的对象,`is`运算符,未绑定的方法对象)
让代码来说明问题:
>>> class A(object):
... a = None
... def b(self):
... pass
...
>>> a = A()
>>> a.a is a.a
True
>>> a.b is a.b
False
>>> class B(object):
... a = None
... @staticmethod
... def b():
... pass
...
>>> b = B()
>>> b.a is b.a
True
>>> b.b is b.b
True
>>> class C(object):
... a = None
... @classmethod
... def b(cls):
... pass
...
>>> c = C()
>>> c.a is c.a …Run Code Online (Sandbox Code Playgroud) 我在跑:
Python 2.7.8 (default, Oct 6 2017, 09:25:50)
GCC 4.1.2 20070626 (Red Hat 4.1.2-14) on Linux 2
Run Code Online (Sandbox Code Playgroud)
根据文件:
运营商
is和is not测试对象标识:x is y是True当且仅当x和y是相同的对象.
为了获得对象的身份,我们可以使用该id功能.
如果我们打开一个新的REPL,我们可以看到它300并-6具有相同的标识(在CPython上,这意味着它们都引用相同的内存地址):
>>> id(300)
94766593705400
>>> id(-6)
94766593705400
Run Code Online (Sandbox Code Playgroud)
请注意,实际值可能因执行而异,但它们始终相等.
然而,做300 is -6收益率False:
>>> 300 is -6
False
Run Code Online (Sandbox Code Playgroud)
我有一些问题:
300和-6分享相同的身份? …python ×11
python-2.7 ×3
identity ×2
python-3.x ×2
cpython ×1
decorator ×1
equality ×1
immutability ×1
interpreter ×1
memory ×1
methods ×1
object ×1
python-2.x ×1
string ×1
unit-testing ×1