亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

python單例模式和魔術方法的實現

發布時間:2020-06-10 15:21:02 來源:億速云 閱讀:472 作者:元一 欄目:編程語言

概述

單例模式,屬于創建類型的一種常用的軟件設計模式。通過單例模式的方法創建的類在當前進程中只有一個實例(根據需要,也有可能一個線程中屬于單例,如:僅線程上下文內使用同一個實例)

魔法方法是python內置方法,不需要主動調用,存在的目的是為了給python的解釋器進行調用,幾乎每個魔法方法都有一個對應的內置函數,或者運算符,當我們對這個對象使用這些函數或者運算符時就會調用類中的對應魔法方法,可以理解為重寫這些python的內置函數。

01_property商品應用.py

分頁顯示是一種非常常見的瀏覽和顯示大量數據的方法,屬于web編程中最常處理的事件之一。

類屬性應用需求: 對于京東商城中顯示電腦主機的列表頁面,每次請求不可能把數據庫
中的所有內容都顯示到頁面上,而是通過分頁的功能局部顯示,所以在向數據庫中請求
數據時就要顯示的指定獲取從第start條到第end條的所有數據 這個分頁的功能包括:
? 根據用戶請求的當前頁和總數據條數計算出 start 和 end
? 根據start 和 end 去數據庫中請求數據
? 是否有上一頁has_prev、下一頁has_next
? 上一頁prev、下一頁next
? 總頁數pages, 數據總條數total、當前頁信息items

"""

class Pagintor(object):
    """實現商品分頁的類"""
    def __init__(self, objects_list, page=1, per_page=5):
        """
        :param objects_list: 商品列表
        :param page: 當前需要顯示的頁碼信息
        :param per_page: 每頁顯示的數據個數
        """
        self.objects_list = objects_list
        self.page = page
        self.per_page = per_page

    @property
    def start(self):
        return (self.page - 1) * self.per_page

    @property
    def end(self):
        return self.page * self.per_page

    @property
    def total(self):
        """
        數據總條數total
        :return:
        """
        return len(self.objects_list)

    @property
    def pages(self):
        """
        總頁數pages
        if 總商品數量%每頁顯示數量==0:  剛好當前頁顯示滿
        else: 好友多與的部分, 在計算的結果上面加1
        self.total = 5  pages=1
        self.total = 6  pages=2
        :return:
        """
        result = self.total // self.per_page
        if self.total % self.per_page == 0:
            return result
        else:
            return result + 1

    @property
    def has_next(self):
        return True if 0 < self.page + 1 <= self.pages else False

    @property
    def next(self):
        next_page = self.page - 1
        next_start = (next_page - 1) * self.per_page
        next_end = self.page * self.per_page
        return self.objects_list[next_start:next_end]

    @property
    def has_prev(self):
        return True if 0 < self.page - 1 <= self.pages else False

    @property
    def prev(self):
        prev_page = self.page - 1
        prev_start = (prev_page - 1) * self.per_page
        prev_end = self.page * self.per_page
        return self.objects_list[prev_start:prev_end]

    @property
    def items(self):
        """
        當前頁信息items
        :return:
        """
        return self.objects_list[self.start:self.end]

if __name__ == '__main__':
    # 應用場景二: 某一個屬性不能直接返回, 需要計算的, 可以通過property屬性實現
    goods = ["電腦" + str(i) for i in range(5)]
    #需求: 顯示第三頁時, 開始的索引是? 結束的索引為多少?
    pagintor = Pagintor(goods, page=1, per_page=6)
    print("第1頁的商品信息為: ", goods[pagintor.start:pagintor.end])
    print("是否有上一頁?", pagintor.has_prev)
    print("總頁數?", pagintor.pages)
"""

02_property通過函數的方式實現類屬性.py

class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.__age = age  #私有屬性

    @property
    def is_age_vaild(self):
        return  0 < self.__age <= 150
    def get_age(self):
        if self.is_age_vaild:
            return self.__age
        else:
            raise Exception("年齡不合法")

    def set_age(self, age):
        if self.is_age_vaild:
            self.__age = age
        else:
            raise Exception("年齡不合法")

    def del_age(self):
        print("年齡屬性刪除......")
    #類屬性 即:在類中定義值為property對象的類屬性
    age = property(fget=get_age, fset=set_age, fdel=del_age)

if __name__ == '__main__':
    p1 = Person("張三", 30)
    print(p1.age)
    p1.age = 31
    print(p1.age)
    del p1.age

03_property通過函數的方式實現類屬性.py

class Person(object):
    def __init__(self, name, age, score):
        self.name = name
        self.__age = age  # 私有屬性
        self.__score = score

    @property
    def score(self):
        return  self.__score
    @score.setter
    def score(self, score):
        self.__score = score

    @property
    def is_age_vaild(self):
        return  0 < self.__age <= 150

    @property           # 獲取age屬性時執行的內容
    def age(self):
        if self.is_age_vaild:
            return self.__age
        else:
            raise Exception("年齡不合法")
    @age.setter         # 設置age屬性時執行的內容
    def age(self, age):
        if self.is_age_vaild:
            self.__age = age
        else:
            raise Exception("年齡不合法")
    @age.deleter        # 刪除age屬性時執行的內容
    def age(self):
        print("年齡屬性刪除......")

if __name__ == '__main__':
    p1 = Person("張三", 30, 100)
    print(p1.age)       # 獲取年齡(), 執行@property def age(self):
    p1.age = 31         # 設置年齡, age=31
    print(p1.age)
    del p1.age          # 刪除年齡屬性

05_裝飾器實現單例模式.py

from functools import wraps
def singleton(cls):
    """
    實現單例模式的裝飾器
    思路: 當實例化對象時, 判斷該類是否實例化過對象。
    - 如果是, 返回之前實例化的對象。
    - 如果不是, 實例化第一個對象, 并將實例化后的對象存儲起來(緩存)。
    """
    instances = {}  # {'Person': obj}

    @wraps(cls)
    def wrapper(*args, **kwargs):
        name = cls.__name__
        if instances.get(name):
            # 直接返回緩存中的對象
            return instances.get(name)
        else:
            # 第一次實例化對象
            obj = cls(*args, **kwargs)
            #類名作為key值, 對象作為value值, 存儲到instances字典中.
            instances[name] = obj
            return obj

    return wrapper

@singleton
class Person(object):
    pass

if __name__ == '__main__':
    p1 = Person()
    p2 = Person()
    #面試題目: ==和is有什么區別?
    print("單例模式是否成功?", p1 is p2)

魔術方法
在Python中,所有用""包起來的方法,都稱為【魔術方法】(eg: len, init__)。
魔術方法一般是為了讓顯示器調用的,你自己并不需要調用它們。
特殊屬性:
python單例模式和魔術方法的實現
dir
查看屬性
返回類或者對象的所有成員名稱列表。dir() 函數就是調用dir()。
1). 如果dir([obj]) 參數obj包含方法 dir(),該方法將被調用。
2). 如果Obj 不包含 dir(),該方法將最大限度收集屬性信息
python 中new , init , call的區別?
1). new的功能是在生成對象之前執行的內容,接受的參數是cls 類, 負責對象的創建
2). init的功能是在對象生成之后執行的內容, 接受的參數是self 對象, 負責對象的初始化
3). call的功能是在調用對象時執行的內容, 可以模擬函數的行為

06_new方法實現單例模式改進版.py

from datetime import  date

class Person(object):
    def __new__(cls, *args, **kwargs):
        print("判斷當前類是否擁有instance屬性?", hasattr(cls, 'instance'))
        if not hasattr(cls, 'instance'):
            cls.instance = super(Person, cls).__new__(cls)
        return  cls.instance

    def __init__(self, name):
        self.name = name

p1 = Person("張三")
p2 = Person("張xxx")
print("單例模式是否成功? ", p1 is p2)

06_通過new方法實現單例模式.py

class Person(object):
    # 1). 設置類屬性, 存儲已經創建好的對象。
    _instance = None
    def __new__(cls, *args, **kwargs):
        print("new方法在實例化對象之前執行.....返回對象本身")
        #2). 判斷是否已經實例化對象?
        if cls._instance:
            return  cls._instance
        else:
            self = object.__new__(cls)
            cls._instance = self
            #返回父類object的new方法創建的對象.....
            return self

    def __init__(self):
        print("構造方法實例化對象之后執行......")

if __name__ == '__main__':
    p1 = Person()
    p2 = Person()
    print(p1, p2)"""

07_call.py

1). new的功能是在生成對象之前執行的內容,接受的參數是cls 類, 負責對象的創建
2). init的功能是在對象生成之后執行的內容, 接受的參數是self 對象, 負責對象的初始化
3). call的功能是在調用對象時執行的內容, 可以模擬函數的行為.
"""

class Person(object):
    def __new__(cls):
        print("__new__")
        return  object.__new__(cls)

    def __init__(self):
        print("__init__")

    def __call__(self, *args, **kwargs):
        print('__call__')

    def __del__(self):
        # 析構方法: 當對象被刪除或者從內存釋放時自動執行
        print("__del__")
p1 = Person()
p1()

08_call魔術方法實現緩存.py

from functools import  lru_cache

class Fib(object):
    @lru_cache(maxsize=1000)
    def __call__(self, n):
        if n in (1, 2):
            return  1
        else:
            return  self(n-1) + self(n-2)
fib = Fib()
print(fib(100))  # 1 1 2 3 5 8"""

可視化
類型判斷要使用type或isinstance, 不能通過判斷print輸出是否帶引號來判斷輸出值的類型。
1). str()與repr()都是python中的內置函數,是直接用來格式化字符串的函數。
2). 當使用內置函數str(obj)時, 自動執行obj.str()魔術方法。
3). 當使用內置函數repr(obj)時, 自動執行obj.repr()魔術方法。
4). 當str魔術方法不存在時, 自動執行repr()魔術方法的內容。
類型轉換
python單例模式和魔術方法的實現

09_可視化魔術方法.py

class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __int__(self):
        return int(self.age)

    #def __str__(self):
    #return  'Person<%s>' %(self.name)
    def __repr__(self):
        return  'Person<%s>' %(self.name)
p1 = Person("fentiao", '100')
print(p1)
print(int(p1))

索引與切片
拓展小知識: slice() 函數實現切片對象,主要用在切片操作函數里的參數傳遞。
索引&切片魔術方法:
setitem:當屬性被以索引、切片方式賦值的時候會調用該方法
getitem:一般如果想使用索引、切片訪問元素時,就可以在類中定義這個方法
delitem:當使用索引、切片刪除屬性時調用該方法

10_魔術方法實現索引和切片.py

class Student(object):
    def __init__(self, name, scores):
        self.name = name
        self.scores = scores

    def __getitem__(self, index):
        """實現獲取索引和切片值的魔術方法"""
        print(index)
        return self.scores[index]
    def __setitem__(self, index, value):
        """實現修改/設置索引和切片值的魔術方法"""
        self.scores[index] = value
    def __delitem__(self, index):
        del self.scores[index]

    def __mul__(self, other):
        """重復操作"""
        return  self.scores * other

    def __add__(self, other):
        """連接操作, 傳入的時對象"""
        return [ item[0]+item[1] for item in zip(self.scores, other.scores)]

    def __contains__(self, item):
        """成員操作符"""
        return  item in self.scores

    def __iter__(self):
        # iter可以將可迭代對象轉換成迭代器(可以調用next方法的)
        return  iter(self.scores)

stu1 = Student("張三", [100, 90, 100])
stu2 = Student("里斯", [100, 80, 100])

#1). 索引和切片的測試
#print(stu1[1:])             # 獲取索引/切片值
#stu1[1:] = (80, 80)        # 設置索引/切片對應的value值
#print(stu1.scores)
#del stu1[1:]                # 刪除索引/切片值
#print(stu1.scores)

##2). 連接、重復和成員操作符
#print(stu1*3)
#print(stu1 + stu2)
#print(150 in stu1)

for item in stu1:
    print(item)

with語句安全上下文
with語句操作的對象必須是上下文管理器。那么,到底什么是上下文管理器呢?
1). 簡單的理解,擁有 enter() 和 exit() 方法的對象就是上下文管理器。
enter(self):進入上下文管理器自動調用的方法,在 with 執行之前執行。如果 有 as子句,該
方法的返回值被賦值給 as 子句后的變量;該方法可以返回多個值。
exit(self, exc_type, exc_value, exc_traceback):退出上下文管理器自動調用的方法。在
with 執行之后執行(不管有無異常)。
2). 當 with as 操作上下文管理器時,就會在執行語句體之前,先執行上下文管理器的 enter() 方法,
然后再執行語句體,最后執行 exit() 方法。
構建上下文管理器,常見的有 2 種方式:基于類實現和基于生成器實現。
方法一: 裝飾器 contextlib.contextmanager,來定義自己所需的基于生成器的上下文管理器
方法二: 基于類的上下文管理器: 只要一個類實現了 enter() 和 exit() 這 2 個方
法,程序就可以使用 with as 語句來管理它

11_魔術方法實現with語句上下文管理器.py

class Connect(object):
    def __init__(self, filename):
        self.filename = filename
    def __enter__(self):
        self.f = open(self.filename)
        return  self.f

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('with語句執行之后......')
        self.f.close()

#Connect就是上下文管理器。 擁有 __enter__() 和 __exit__() 方法的對象就是上下文管理器
with Connect('/etc/passwd') as conn:
    pass

12_裝飾器實現上下文管理器的方法.py

import  contextlib
import  tempfile
import  shutil

@contextlib.contextmanager
def make_temp_dir():
    try:
        tmp_dir = tempfile.mkdtemp()
        yield  tmp_dir
    finally:
        shutil.rmtree(tmp_dir)
with make_temp_dir() as f:
    pass

13_比較大小.py

class Int(object):
    def __init__(self, number, weight):
        self.number = number
        self.weight = weight

    def __gt__(self, other):
        """判斷大于的魔術方法"""
        return  self.number * self.weight > other.number * other.weight

    def __ge__(self, other):
        """判斷大于等于的魔術方法"""
        return  self.number * self.weight >= other.number * other.weight

    def __eq__(self, other):
        """判斷等于的魔術方法"""
        return self.number * self.weight == other.number * other.weight

i1 = Int(20, 3)
i2 = Int(20, 3)
print(i1 > i2)
print(i1 < i2)
print(i1 >= i2)
print(i1 == i2)
print(i1 != i2)

01_call魔術方法實現類裝飾器.py

from  functools import  wraps
import time
def timeit(unit='s'):
    def wrapper1(fun):  # fun=add
        @wraps(fun)
        def wrapper(*args, **kwargs):
            if unit == 's':
                start_time = time.time()
                result = fun(*args, **kwargs)       # add(1, 2)  result=3
                end_time = time.time()
                print("%s函數運行時間為%.2f s" %(fun.__name__, end_time-start_time))
                return  result
            else:
                print("當前功能不支持......")
        return  wrapper
    return  wrapper1

#類裝飾器: 裝飾器需要傳遞的參數通過__init__傳遞進入.被裝飾函數執行的內容在__call__魔術方法中編寫。
class TimeIt(object):
    def __init__(self, unit='s'):
        self.unit = unit
    def __call__(self,fun):
        @wraps(fun)
        def wrapper(*args, **kwargs):
            if self.unit == 's':
                start_time = time.time()
                result = fun(*args, **kwargs)  #add(1, 2)   result=3
                end_time = time.time()
                print("%s函數運行時間為%.2f s" % (fun.__name__, end_time - start_time))
                return result
            else:
                print("當前功能不支持......")
        return  wrapper
#@timeit(unit='s')       #@wrapper1 ==> add = wrapper1(add)  ===> add =wrapper
#def add(num1, num2):
#time.sleep(0.333)
#return  num1 + num2

"""
@TimeIt(unit='h') 
#1). TimeIt_obj = TimeIt(unit='h')  
#2). @TimeIt_obj
#3). add=TimeIt_obj(add)
#4). add = wrapper
"""
@TimeIt(unit='s')
def add(num1, num2):
    time.sleep(0.333)
    return  num1 + num2

#add(1, 2)  ==> wrapper(1, 2)
add(1, 2)

02_call魔術方法實現偏函數.py

from functools import  partial

max_100 = partial(max,10, 100)  # 返回對象
print(max_100(1, 2, 3))   # 100"""

03_基于call魔術方法和filter實現文件過濾器.py

from wtforms    import  StringField,SubmitField
import os
#作為基類/父類
class FileAcceptor(object):
    def __init__(self, accepted_extensions):
        """
        eg: ['.png', '.jpg']
        :param accepted_extensions: 可以接受的擴展名
        """
        self.accepted_extensions = accepted_extensions

    def __call__(self, filename):
        """
        eg: hello.jpg
        :param filename: 需要判斷的文件名
        :return:
        """
        #base = 'hello', ext='.jpg'
        base, ext = os.path.splitext(filename)
        return  ext in self.accepted_extensions

#子類
class ImageFileAcceptor(FileAcceptor):
    def __init__(self):
        image_ext = ('.jpg', '.jepg', '.png')
        super(ImageFileAcceptor, self).__init__(image_ext)

#子類
class ExcelFileAcceptor(FileAcceptor):
    def __init__(self):
        image_ext = ('.xls', '.xlsx')
        super(ExcelFileAcceptor, self).__init__(image_ext)

if __name__ == '__main__':
    filenames = [
        'hello.jpg',
        'hello.xls',
        'hello.txt'
    ]
    """
    1). ImageFileAcceptor() 實例化對象, 執行__new__和__init__魔術方法。
    2). imagefileacceptor_obj
    3). imagefileacceptor_obj('hello.jpg')  True
    3). imagefileacceptor_obj('hello.xls')  False
    3). imagefileacceptor_obj('hello.txt')  False
    4). ['hello.jpg']

    """
    images_file = filter(ImageFileAcceptor(), filenames)
    excels_file = filter(ExcelFileAcceptor(), filenames)
    print(list(images_file))
    print(list(excels_file))

04_通過分支語句動態的創建類.py

def create_class(name):
    if name == 'foo':
        class Foo(object):
            pass
        return  Foo
    else:
        class Bar(object):
            pass
        return  Bar

cls = create_class(name='foo1')
print(cls.__name__)

05_通過type動態地創建類.py

#type函數語法:
#type(類名, 父類名稱的元組, 屬性信息)
#class Person(object):
#country= 'China'

def hello(self):
    print("hello")
Person = type('Person',(object, ), {'country':'China', 'hello':hello})
p1 = Person()
print(p1.country)
p1.hello()

魔術方法匯總
基本的魔法方法
有關屬性的魔術方法
比較操作符
算數運算符
反運算
增量賦值運算
一元操作符
類型轉換
上下文管理(with 語句)
容器類型
python單例模式和魔術方法的實現

元類
類也是對象
Python一切皆對象
Linux一切皆文件
元類是類的類,是類的模板
元類的實例為類,正如類的實例為對象。
類的本質是對象, 于是可以對類做如下的操作:

  1. 你可以將它賦值給一個變量
  2. 你可以拷?它
  3. 你可以為它增加屬性
  4. 你可以將它作為函數參數進行傳遞
    1). 元類就是創建類的類。函數type就是是元類。
    2). Python中一切皆對象。包括整數、字符串、函數以及類都是對象,且都是從type類創建而來。
    3). 動態生成類,不能控制類是如何生成的。python3 的metaclass可動態創建類。
    4). 很多Web框架都會使用metaclass 來創建類。掌握元類對理解源代碼至關重要。eg: ORM框架類

    06_metaclass自定義元類.py

    #實現單例模式的方法:
    #1. 裝飾器
    #2. new魔術方法
    #3. metaclass自定義元類

class Singleton(type):
    type(name, bases, attrs)
    自定義元類實現單例模式, 父類是type
    #所有類和實例化對象之間的關系; eg: {'Person': Pseron()}
    cache = {}

    #1). 為什么是__call__魔術方法?
    def __call__(cls):
        #判斷類是否已經實例化, 如果沒有, 實例化后存儲到緩存中。 最后將緩存的信息返回給用戶。
        if cls not in  cls.cache:
            cls.cache[cls] = super(Singleton, cls).__call__()
        return  cls.cache[cls]

#type('Pseron', (), {})
#創建以各類Person, 指定創建Person類的類(元類)是type.
#2. metaclass是在做什么? 指定元類為Singleton。
class Person(object, metaclass=Singleton):  # Person = Singleton.__new__(Person, (objects, ), {})
    pass

#Person是Singleton元類實例化出的對象, Person()就是對象(), 執行Singleton.__call__魔術方法.
p1 = Person()
p2 = Person()
print(p1, p2)

#99%情況不需要自己自定義元類。

抽象基類
抽象基類有兩個特點:
1.規定繼承類必須具有抽象基類指定的方法
2.抽象基類無法實例化
基于上述兩個特點,抽象基類主要用于接口設計
實現抽象基類可以使用內置的abc模塊

07_抽象基類.py

import abc
class Human(metaclass=abc.ABCMeta):
    """基類, 定義一個抽象類"""
    @abc.abstractmethod
    def introduce(self):
        print("introduce.....")
    @abc.abstractmethod
    def hello(self):
        print('hello')

class Person(Human):
    # 1).規定繼承類必須具有抽象基類指定的方法
    def introduce(self):
        print('person')
    def hello(self):
        print('person hello')

#2). 抽象基類無法實例化
#h = Human()
p = Person()
p.introduce()
p.hello()

動態語言與靜態語言的不同?

  1. 動態語言:可以在運行的過程中,修改代碼
  2. 靜態語言:編譯時已經確定好代碼,運行過程中不能修改
    slots
    如果我們想要限制實例的屬性怎么辦?
  3. Python允許在定義class的時候,定義一個特殊的slots變量,來限制該class實例能添加的屬性
  4. 使用slots要注意,slots定義的屬性僅對當前類實例起作用,對繼承的子類是不起作用的

    08_slots限制對象屬性.py

import time
from datetime import  date
#d = date.today()
#print("對象類型: ", type(d))        # <class 'datetime.date'>
#print("判斷是否有year這個屬性?", hasattr(d, 'year')) # True
#print("判斷是否有time這個屬性?", hasattr(d, 'time')) # False
##setattr(d, 'time', '10:10:10')  # 報錯
class Date(object):
    # __slots__ 來限制該對象能添加的屬性信息
    __slots__ =  '__year', '__month', '__day'
    def __new__(cls, year, month, day):
        self = object.__new__(cls)
        self.__year = year
        self.__month = month
        self.__day = day
        return  self
    @property
    def year(self):
        return  self.__year

    @property
    def month(self):
        return self.__month

    @property
    def day(self):
        return self.__day
    @classmethod
    def today(cls):
        time_t = time.localtime()
        return  cls(time_t.tm_year, time_t.tm_mon, time_t.tm_mday)

    def __str__(self):
        return  '%s-%s-%s' %(self.__year, self.__month, self.__day)
d = Date(2019, 10, 10)
print("對象類型: ", type(d))        # <class 'datetime.date'>
print("判斷是否有year這個屬性?", hasattr(d, 'year')) # True
print("判斷是否有time這個屬性?", hasattr(d, 'time')) # False
#setattr(d, 'time', '10:10:10')      # Error
#print('time:', getattr(d, 'time'))  # Error

print(Date.today())

09_垃圾回收機制.py

#1). 整數在程序中的使用非常廣泛,Python為了優化速度,使用了小整數對象池,
#避免為整數頻繁申請和銷毀內存空間。

#2). Python對小整數的定義是[-5,257)
>>> a = 1
>>> id(a)
139883638752032
>>> b = 1
>>> id(b)
139883638752032
>>> c = 257
>>> d = 257
>>> id(c), id(d)
(139883633580400, 139883633580432)
>>> e=-5;f=-5
>>> id(e), id(f)
(139883638751840, 139883638751840)

#********************************2. 字符串駐留機制 ********************************
#1). string interning(字符串駐留): 它通過維護一個字符串常量池(string intern pool),
#從而試圖只保存唯一的字符串對象,達到既高效又節省內存地處理字符串的目的。
>>> a = 'hello'
>>> b = 'hello'
>>> id(a), id(b)
(139883511138480, 139883511138480)
>>> c = 'pythonchjdshfcejhfkjrehfkjrehfkjrehfregjrkhgkjrg'
>>> d = 'pythonchjdshfcejhfkjrehfkjrehfkjrehfregjrkhgkjrg'
>>> id(c),id(d)
(139883633099360, 139883633099360)

#2). 字符串(含有空格),不可修改,沒開啟intern機制,不共用對象,引用計數為0,銷毀。
>>> a = 'a b'
>>> b = 'a b'
>>> id(a), id(b)
(139883511138608, 139883511138544)

10_引用計數機制.py

#導致引用計數+1的情況
>>> #1). 對象被創建,例如a=23
...
>>> name = 'fentiao'
>>>
>>> #2). 對象被作為參數,傳入到一個函數中
...
>>> import sys
>>> sys.getrefcount(name)
2
>>> #3). 對象被引用,例如b=a
...
>>> cat_name = name
>>> sys.getrefcount(name)
3
>>> #4). 對象作為一個元素,存儲在容器中,例如list1=[a,a]
...
>>> l = [name, 'hello', 'python']
>>> sys.getrefcount(name)
4

#***************************導致引用計數-1的情況*************************
>>> #1). 對象的別名被顯式銷毀,例如del a
...
>>> del cat_name
>>> sys.getrefcount(name)
3
>>> #2). 對象的別名被賦予新的對象,例如a=24
>>> name1 = name
>>> sys.getrefcount(name)
4
>>> name1 = 'hello'
>>> sys.getrefcount(name)
3
>>> #4). 對象所在的容器被銷毀,或從容器中刪除對象
...
>>> l
['fentiao', 'hello', 'python']
>>> del l[0]
>>> sys.getrefcount(name)
2

#****************************gc模塊使用***********************************
#1). 分代回收的頻率
>>> gc.get_threshold()
(700, 10, 10)
>>>gc.set_threshold(700, 90, 90)
KeyboardInterrupt

#2). 垃圾回收機制是否開啟
>>>gc.isenabled()
True
>>>gc.disable()
>>>gc.isenabled()
False
>>> gc.enable()
>>>gc.isenabled()
True

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

菏泽市| 莱阳市| 阳江市| 精河县| 玉门市| 临武县| 南开区| 玛沁县| 峡江县| 弥渡县| 布尔津县| 咸宁市| 汾西县| 临沭县| 贺兰县| 南宫市| 泰来县| 连云港市| 铅山县| 嘉义市| 县级市| 邳州市| 静海县| 天气| 高邑县| 腾冲县| 隆子县| 九江市| 昌图县| 仲巴县| 当涂县| 中卫市| 安岳县| 辽宁省| 封丘县| 周至县| 武汉市| 吉木萨尔县| 新干县| 清涧县| 肃宁县|