• <sup id="mk476"></sup>
    <dl id="mk476"></dl>
  • <progress id="mk476"><tr id="mk476"></tr></progress>
    <div id="mk476"><tr id="mk476"></tr></div>
    <sup id="mk476"><ins id="mk476"></ins></sup>
  • <progress id="mk476"></progress>
    <div id="mk476"></div>
    <div id="mk476"><tr id="mk476"></tr></div>
  • <div id="mk476"></div>
    <dl id="mk476"><s id="mk476"></s></dl><dl id="mk476"></dl><div id="mk476"></div>
  • <div id="mk476"></div>
    <dl id="mk476"><ins id="mk476"></ins></dl>

    python 對象/變量&賦值的幾點思考

    python 對象/變量

    對象

    Every object has an identity, a type and a value.

    1. An object’s identity never changes once it has been created; you may think of it as the object’s address in memory. The ‘is’ operator compares the identity of two objects; the id() function returns an integer representing its identity (currently implemented as its address).
    2. An object’s type is also unchangeable. The type() function returns an object’s type (which is an object itself).
    3. The value of some objects can change. Objects whose value can change are said to be mutable; objects whose value is unchangeable once they are created are called immutable.
    1. 不可變(immutable)對象:

      numbers, strings and tuples, etc.
      可變對象的id基本上可以理解為該對象內存地址,而python中命名空間內的對象總是以標簽的方式來操作,例如a=3,它會在內存中尋找一個int類型的value為3的對象,如果有則將其內存地址作為a的id,假如沒有這樣的對象,則會先新建一個int類型的value為3的對象,再將其內存地址作為a的id。

       class Obj():
           def __init__(self,arg):
               self.x=arg
       if __name__ == '__main__':
      
           obj=Obj(1)
           print id(obj)       #32754432
           obj.x=2
           print id(obj)       #32754432
      
           s="abc"
           print id(s)         #140190448953184
           s="bcd"
           print id(s)         #32809848
      
           x=1
           print id(x)         #15760488
           x=2
           print id(x)         #15760464
    2. 可變(mutable)對象:

      dictionaries and lists, etc.、
      在python中不可變對象總是唯一的,即使兩個列表的大小,value對相同,但他們的id絕不可能相同,這是因為對象是可變的,假如id相同,則兩個變量將可以協同變化。

       class Obj():
           def __init__(self,arg):
               self.x=arg
           def __eq__(self,other):
               return self.x==other.x
           
       if __name__ == '__main__':
          
           obj1=Obj(1)
           obj2=Obj(1)
           print obj1 is obj2  #False
           print obj1 == obj2  #True
           
           lst1=[1]
           lst2=[1]
           print lst1 is lst2  #False
           print lst1 == lst2  #True
           
           s1='abc'
           s2='abc'
           print s1 is s2      #True
           print s1 == s2      #True
           
           a=2
           b=1+1
           print a is b        #True
           
           a = 19998989890
           b = 19998989889 +1
           print a is b        #False

    對象賦值

    在python中一切皆為對象,賦值操作即是改變命名空間中的相應名字的指針,在相應的對象上即使反映為:從一個對象上撕下標簽,再將該標簽打到另外一個對象上。
    對于可變對象來說,即為id地址的改變。

    def fun(a):
        print "id(a):", id(a)  # 56715624
        a = 4
        print "id(a):", id(a)  # 56715600
        print "a:", a
    
    b = 3
    print "id(3):", id(3)   # 56715624
    fun(b)
    print "id(b):", id(b)   # 56715624
    print 'b:', b

    首先創建了對象int 3,該對象即有了一個id,再將其賦值給b(屬于全局名字空間),b的id與int 3的id相同,所以b指向了3.再進行函數操作fun(b)時,首先進行了a=b=3的操作,a與b與3的id相同,共同指向對象3,然后a又進行了賦值操作,因為對象是不可變的(type決定了),所以必須新建對象int 4,并將a指向4,所以a的id改變了,a的value也相應的改變了。但是b是屬于全局名字空間的,b并沒有受到影響。

    對于可變變量(列表)

    def fun(a):
        print "id(a):", id(a)  # 63265352   a=b的操作,a、b的id相同
        print a                # [3, [2, 3]]    
        print id(c)            # 57698664   指向全局變量c
        a[0] = 1
        print "id(a):", id(a)  # 63265352   修改了a的value,但是id并未改變
    
    c = 3
    b = [c, [2, 3]]
    print "id(c):", id(c)   # 57698664
    print "id(b):", id(b)   # 63265352
    fun(b)
    print "id(b):", id(b)   # 63265352
    print 'b:', b           # [1, [2, 3]]   b的id與a相同,a、b的value同時改變

    在此處賦值時,先進行a=b的操作,a、b的id相同,所以在fun內改變了a[0],b也被改變了。

    def fun(a):
        print "id(a):", id(a)  # 54309000   由于進行了copy操作,所以相當于傳遞了一個新的列表id給a,a的id與b則不相同了,
        a上的淺層(axis=0)修改對b不起作用,但深層次(axis>0)的修改依然有效嗎,這是因為此時a[1]與b[1]都指向同一個列表。
        print a[0] is b[0]     # False
        print a[1] is b[1]     # True
        print a                # [3, [2, 3]]
        a[0] = 1
        a[1][0] = 0
        print a                # [1, [0, 3]]
    
    c = 3
    b = [c, [2, 3]]
    print "id(c):", id(c)   # 52455784
    print "id(b):", id(b)   # 54286920
    fun(b[:])               # 對b進行切片操作,即等于copy.copy(b)
    print "id(b):", id(b)   # 54286920
    print 'b:', b           # [3, [0, 3]]

    對列表的復制會產生一個新的列表,與新的列表id。
    切片操作與淺層復制是相等的:a[:] 等價于 copy.copy[a]
    深層復制可以迭代copy操作,使得列表中的列表也被復制,即完全產生一個新的value相同的列表,新列表與舊列表沒有任何聯系,對列表中的列表的修改不會影響原列表。可以寫成copy.deepcopy(b)。


    Reference

    Python中的id函數到底是什么?
    python基礎(5):深入理解 python 中的賦值、引用、拷貝、作用域

    posted @ 2018-09-22 17:33 海不厭深 閱讀(...) 評論(...) 編輯 收藏
    江苏11选5软件