เมื่อใดที่ del มีประโยชน์ใน python


374

ฉันไม่สามารถคิดด้วยเหตุผลใด ๆ ว่าทำไมไพ ธ อนต้องการdelคำหลัก (และภาษาส่วนใหญ่ดูเหมือนจะไม่มีคำหลักที่คล้ายกัน) ตัวอย่างเช่นแทนที่จะลบตัวแปรคนหนึ่งสามารถกำหนดNoneให้มันได้ และเมื่อลบจากพจนานุกรมdelสามารถเพิ่มวิธีการได้

มีเหตุผลใดที่จะเก็บไว้delในงูหลามหรือเป็นร่องรอยของวันเก็บขยะล่วงหน้าของ Python?


46
ประวัติที่ผ่านมา : Python มีการรวบรวมขยะตั้งแต่เริ่มต้น ก่อนที่จะมี 2.0, เก็บขยะ ธ ไม่สามารถตรวจสอบรอบของการอ้างอิง delแต่ที่ไม่ได้มีอะไรจะทำอย่างไรกับ
Steven Rumbalski

28
@ Steven Rumbalksi มันมีบางอย่างที่เกี่ยวข้องกับ del Del ถูกใช้เพื่อแบ่งรอบการอ้างอิง
Winston Ewert

6
แต่delไม่ได้เป็น vestigate used = Noneของการเก็บขยะก่อนเพราะคุณอาจจะมี มันสมเหตุสมผลเสมอที่จะมีไวยากรณ์เฉพาะสำหรับมัน เนื่องจากเรามี GC แบบทรงกระบอกในขณะนี้กรณีที่คุณต้องการใช้อย่างใดอย่างหนึ่งมีขนาดเล็ก
Winston Ewert

3
> และภาษาส่วนใหญ่ดูเหมือนจะไม่มีคำหลักที่คล้ายกันภาษาส่วนใหญ่ที่รวบรวมขยะไม่ได้ (หรือใช้เพื่อบอกใบ้ถึง GC ว่าสามารถรวบรวมตัวแปรได้) ภาษาที่เก่าแก่ที่สุดส่วนใหญ่ทำ: - ภาษาพื้นฐานดี ๆ เช่น QuickBasic มีERASE(ฆ่าตัวแปรเฉพาะ) และCLEAR(ฆ่าตัวแปรทั้งหมด )
DrYak

คำตอบ:


499

ประการแรกคุณสามารถลบสิ่งอื่น ๆ นอกเหนือจากตัวแปรท้องถิ่น

del list_item[4]
del dictionary["alpha"]

ทั้งสองอย่างควรมีประโยชน์อย่างชัดเจน ประการที่สองการใช้delตัวแปรท้องถิ่นทำให้เจตนาชัดเจนขึ้น เปรียบเทียบ:

del foo

ถึง

foo = None

ฉันรู้ในกรณีdel fooที่เจตนาคือการลบตัวแปรออกจากขอบเขต ไม่ชัดเจนว่าfoo = Noneจะทำเช่นนั้น หากใครบางคนเพิ่งได้รับมอบหมายfoo = Noneฉันอาจคิดว่ามันเป็นรหัสตาย แต่ฉันรู้ทันทีว่ามีใครบางคนdel fooกำลังพยายามทำรหัส


51
+1 ใช่ เมื่อคุณกำหนดบางอย่างมันจะสื่อถึงความตั้งใจที่จะใช้ในภายหลัง ฉันเห็นจริง ๆ แล้วว่าdelใช้ในการคำนวณหน่วยความจำมาก แต่เมื่อฉันเห็นมันฉันก็รู้ได้ทันทีว่าทำไมมันถึงจำเป็น
detly

17
การใช้กรณีการลบจากรายการหรือพจนานุกรมสามารถแทนที่ด้วยวิธีการได้อย่างง่ายดาย (ดังที่ฉันบันทึกไว้ในคำถาม) ฉันไม่แน่ใจว่าฉันเห็นด้วยกับการใช้delเพื่อส่งสัญญาณความตั้งใจ (เนื่องจากความคิดเห็นสามารถทำได้โดยไม่ต้องเพิ่มภาษา) แต่ฉันคิดว่านั่นเป็นคำตอบที่ดีที่สุด
Jason Baker

6
@ JasonBaker ให้สิทธิ์กับวิธีการ การลบสไลซ์และสิ่งดังกล่าวอาจทำให้อึดอัดใจมากขึ้นโดยใช้วิธีการ ใช่คุณสามารถใช้ความคิดเห็น แต่ฉันคิดว่าการใช้ข้อความจะดีกว่าถ้ามีความคิดเห็นเป็นส่วนหนึ่งของภาษา
Winston Ewert

2
@ JasonBaker: มันไม่เพียง แต่เกี่ยวกับความตั้งใจไวยากรณ์ทั้งสองนั้นทำสองสิ่งที่แตกต่างกันมาก
Pavel Šimerda

2
นอกจากนี้ยังจัดการโดยการลบออกจากพจนานุกรมที่เกี่ยวข้อง คุณสามารถโต้แย้งlen()ฟังก์ชั่นแบบเดียวกันได้ หากเป็นกรณีนี้อาจมีการปิด Quesition ตามความคิดเห็นหรือแม้แต่รสนิยม Python มีแนวโน้มที่จะให้บริการพื้นฐานสำหรับการดำเนินงานขั้นพื้นฐานแทนการพึ่งพาวิธีการ
Pavel Šimerda

161

นี่เป็นส่วนหนึ่งของสิ่งที่delทำ (จากการอ้างอิงภาษา Python ):

การลบชื่อจะลบการเชื่อมโยงของชื่อนั้นออกจากเนมสเปซท้องถิ่นหรือส่วนกลาง

การกำหนดNoneให้กับชื่อจะไม่ลบการเชื่อมโยงของชื่อออกจากเนมสเปซ

(ฉันคิดว่าอาจมีการถกเถียงกันบ้างเกี่ยวกับว่าการลบการโยงชื่อนั้นมีประโยชน์จริงหรือไม่


22
-1 ผู้โพสต์เข้าใจเรื่องนี้ชัดเจนแล้วเขาถามว่าทำไมคุณถึงต้องการลบชื่อ
Winston Ewert

71
@Winston Ewert: ฉันไม่แน่ใจว่าผู้โพสต์เข้าใจว่าdelจะลบการผูกชื่อตามที่เขาแนะนำให้มอบหมายNoneเป็นทางเลือก
Steven Rumbalski

8
@Steven โปสเตอร์จะลบความแตกต่างอย่างชัดเจน (ลบชื่อ) และกำหนดไม่มี เขาไม่เห็นว่าทำไมคุณควรลบตัวแปรเมื่อคุณสามารถกำหนดไม่มี มีผลเช่นเดียวกันกับที่พวกเขาปล่อยการอ้างอิงถึงสิ่งที่เคยผูกไว้กับชื่อนั้น
Winston Ewert

19
@Winston Ewert: มันไม่ชัดเจนสำหรับฉัน บางทีอาจเป็นเรื่องที่ชัดเจนสำหรับคุณในการที่คุณระบุว่าพวกเขา "มีผลเช่นเดียวกันกับการที่ปล่อยการอ้างอิงถึงสิ่งที่ถูกผูกไว้กับชื่อก่อนหน้านี้" แต่ที่ (อย่างชัดเจน?) NameErrorไม่ได้เป็นเรื่องราวทั้งหมดในความพยายามที่จะใช้ชื่อหลังจากลบมันยก Greg Hewgill สร้างความแตกต่างอย่างมาก และนี่คือความแตกต่างที่ทำให้คุณยืนยันในสิ่งที่โปสเตอร์ "ชัดเจน" เข้าใจชัดเจนสำหรับฉัน
Steven Rumbalski

9
@Winston Ewert ฉันไม่เห็นด้วย แต่พอพูดไป เราทั้งคู่ทำเรื่องของเรา
Steven Rumbalski

44

ที่เดียวที่ฉันพบว่าdelมีประโยชน์คือการทำความสะอาดตัวแปรภายนอกสำหรับลูป:

for x in some_list:
  do(x)
del x

ตอนนี้คุณสามารถมั่นใจได้ว่า x จะไม่ถูกกำหนดถ้าคุณใช้มันนอกวง for


1
delบรรทัดของคุณที่นี่ควรจะเยื้อง (เช่นส่วนหนึ่งของวง)?
Sam

11
@ แซมพวกเขาไม่ได้ตั้งใจ
user5319825

7
@Sam ไม่แนวคิดที่นี่คือหลังจากวนซ้ำครั้งสุดท้ายของลูป (หลังจากดำเนินการ do () ในองค์ประกอบสุดท้ายของ some_list) x จะยังคงอ้างอิงถึงค่าสุดท้ายของ some_list del x ทำให้แน่ใจว่าสิ่งนี้จะไม่ถูกกำหนดเช่นนี้
Matthew

12
สิ่งนี้จะทำให้เกิดNameError: name 'x' is not definedถ้ารายการว่างเปล่า
WofWca

18

การลบตัวแปรแตกต่างจากการตั้งค่าเป็นไม่มี

การลบชื่อตัวแปรด้วยdelอาจเป็นสิ่งที่ไม่ค่อยได้ใช้ แต่เป็นสิ่งที่ไม่สามารถทำได้โดยไม่ต้องใช้คำสำคัญ หากคุณสามารถสร้างชื่อตัวแปรได้โดยการเขียนa=1มันเป็นเรื่องดีที่คุณสามารถเลิกทำสิ่งนี้ได้ในทางทฤษฎีโดยการลบ

มันสามารถทำให้การดีบักง่ายขึ้นในบางกรณีเนื่องจากการพยายามเข้าถึงตัวแปรที่ถูกลบจะเพิ่ม NameError

คุณสามารถลบแอ็ตทริบิวต์คลาสอินสแตนซ์

Python ช่วยให้คุณเขียนสิ่งที่ชอบ:

class A(object):
    def set_a(self, a):
        self.a=a
a=A()
a.set_a(3)
if hasattr(a, "a"):
    print("Hallo")

หากคุณเลือกที่จะเพิ่มแอททริบิวไปยังอินสแตนซ์ของคลาสคุณจะต้องยกเลิกการเขียนมันอย่างแน่นอน

del a.a

16

มีตัวอย่างเฉพาะเมื่อคุณควรใช้del(อาจมีคนอื่น แต่ฉันรู้เกี่ยวกับมือนี้) เมื่อคุณใช้sys.exc_info()ในการตรวจสอบข้อยกเว้น ฟังก์ชันนี้ส่งคืน tuple ชนิดของข้อยกเว้นที่เพิ่มขึ้นข้อความและการติดตามกลับ

โดยปกติค่าสองค่าแรกจะเพียงพอในการวิเคราะห์ข้อผิดพลาดและดำเนินการกับค่านั้น แต่ค่าที่สามจะมี call stack ทั้งหมดระหว่างที่มีการยกข้อยกเว้นและที่ที่มีการยกเว้น โดยเฉพาะถ้าคุณทำอะไรที่ชอบ

try:
    do_evil()
except:
    exc_type, exc_value, tb = sys.exc_info()
    if something(exc_value):
        raise

traceback tbสิ้นสุดลงในท้องถิ่นของ call stack สร้างการอ้างอิงแบบวงกลมที่ไม่สามารถรวบรวมขยะได้ ดังนั้นจึงเป็นสิ่งสำคัญที่จะทำ:

try:
    do_evil()
except:
    exc_type, exc_value, tb = sys.exc_info()
    del tb
    if something(exc_value):
        raise

เพื่อทำลายการอ้างอิงแบบวงกลม ในหลาย ๆ กรณีที่คุณต้องการโทรsys.exc_info()เช่นเดียวกับ metaclass magic การสืบค้นกลับมีประโยชน์ดังนั้นคุณต้องตรวจสอบให้แน่ใจก่อนว่าคุณล้างมันก่อนที่จะออกจากตัวจัดการข้อยกเว้น หากคุณไม่ต้องการการสืบค้นกลับคุณควรลบทันทีหรือเพียงแค่ทำสิ่งต่อไปนี้

exc_type, exc_value = sys.exc_info()[:2]

เพื่อหลีกเลี่ยงมันทั้งหมดเข้าด้วยกัน


18
ไม่เป็นความจริงอีกต่อไปที่ตัวรวบรวมขยะจะไม่รวบรวม อย่างไรก็ตามวงจรจะชะลอการรวบรวม
Winston Ewert

สิ่งนี้ไม่เกี่ยวข้องเกินไปและไม่ตอบคำถามของ op
WhyNotHugo

15

อีกความคิดหนึ่ง

เมื่อทำการดีบั๊กแอพพลิเคชั่น http ในกรอบงานเช่น Django การเรียกสแต็คที่เต็มไปด้วยตัวแปรที่ไร้ประโยชน์และทำให้ยุ่งเหยิงก่อนหน้านี้ที่ใช้โดยเฉพาะอย่างยิ่งเมื่อมันเป็นรายการที่ยาวมาก ดังนั้น ณ จุดนี้การควบคุมเนมสเปซอาจมีประโยชน์


12

การใช้ "del" อย่างชัดเจนก็ดีกว่าการกำหนดตัวแปรให้กับ None หากคุณพยายามที่จะลบตัวแปรที่ไม่มีอยู่คุณจะได้รับข้อผิดพลาดรันไทม์ แต่ถ้าคุณพยายามตั้งค่าตัวแปรที่ไม่มีอยู่ Python จะตั้งค่าตัวแปรใหม่ให้ไม่มี None โดยไม่แจ้งให้ทราบ ต้องการลบในที่ที่มันอยู่ ดังนั้นเดลจะช่วยคุณจับข้อผิดพลาดก่อนหน้านี้


11

วิธีเพิ่มคะแนนสองสามข้อให้กับคำตอบด้านบน: del x

ความหมายของการxบ่งชี้r -> o(อ้างอิงrที่ชี้ไปยังวัตถุo) แต่del xการเปลี่ยนแปลงมากกว่าr oมันเป็นงานในการอ้างอิง (ชี้) xที่จะคัดค้านมากกว่าวัตถุที่เกี่ยวข้องกับ แยกความแตกต่างระหว่างrและoเป็นกุญแจสำคัญที่นี่

  • locals()มันเอามันออกมาจาก
  • ลบออกglobals()หากxอยู่ในที่นั้น
  • ลบออกจากกรอบสแต็ก (ลบการอ้างอิงทางกายภาพออกจาก แต่วัตถุเองอยู่ในกลุ่มวัตถุและไม่อยู่ในกรอบสแต็ก)
  • ลบออกจากขอบเขตปัจจุบัน มันมีประโยชน์มากในการ จำกัด ช่วงการกำหนดตัวแปรท้องถิ่นซึ่งอาจทำให้เกิดปัญหาได้
  • มันเกี่ยวกับการประกาศชื่อมากกว่าคำจำกัดความของเนื้อหา
  • มันมีผลต่อที่xเป็นของไม่ได้อยู่ที่xจุด การเปลี่ยนแปลงทางกายภาพในหน่วยความจำเพียงอย่างเดียวคือสิ่งนี้ ตัวอย่างเช่นถ้าxอยู่ในพจนานุกรมหรือรายการมัน (เป็นการอ้างอิง) จะถูกลบออกจากที่นั่น (และไม่จำเป็นต้องมาจากกลุ่มวัตถุ) ในตัวอย่างนี้พจนานุกรมมันเป็นกรอบสแต็ค ( locals()) globals()ซึ่งคาบเกี่ยวกับ

6

บังคับปิดไฟล์หลังจากใช้ numpy.load:

บางทีการใช้งานแบบโพรง แต่ฉันพบว่ามีประโยชน์เมื่อใช้numpy.loadในการอ่านไฟล์ ทุกครั้งที่ฉันจะอัปเดตไฟล์และจำเป็นต้องคัดลอกไฟล์ที่มีชื่อเดียวกันไปยังไดเรกทอรี

ฉันเคยdelปล่อยไฟล์และอนุญาตให้ฉันคัดลอกในไฟล์ใหม่

หมายเหตุฉันต้องการหลีกเลี่ยงการwithจัดการบริบทขณะที่ฉันกำลังเล่นกับพล็อตในบรรทัดคำสั่งและไม่ต้องการกดแท็บมาก!

ดูนี้คำถาม


ฉันมีบางสิ่งที่คล้ายกับรูปภาพที่โหลดด้วย Python Image Library (PIL) ฉันเปิดภาพและหากมีขนาดที่แน่นอนฉันต้องการลบไฟล์; อย่างไรก็ตามไฟล์นั้นยังคงใช้งานโดย Python ดังนั้นฉันจึงพูดว่า 'del img' จากนั้นสามารถลบไฟล์ได้
ทางกายภาพ

2
ระวังว่านี้เป็นรายละเอียดการดำเนินงานเป็นรายละเอียดเฉพาะภาษาที่ไม่รับประกันเมื่อ__del__()วิธีการเกี่ยวกับขยะที่เรียกว่าวัตถุหรือแม้กระทั่งถ้ามันได้รับการเรียกที่ทั้งหมด ดังนั้น API ที่เสนอวิธีที่จะไม่ปล่อย ressources อื่น ๆ นอกจากหวังว่า__del__()วิธีการที่จะได้รับเรียกบางครั้ง
BlackJack

6

delมักจะเห็นใน__init__.pyไฟล์ ตัวแปรโกลบอลใด ๆ ที่กำหนดไว้ใน__init__.pyไฟล์จะถูก "ส่งออก" โดยอัตโนมัติ (ซึ่งจะรวมอยู่ใน a from module import *) วิธีหนึ่งในการหลีกเลี่ยงสิ่งนี้คือการกำหนด__all__แต่สิ่งนี้อาจทำให้เกิดความยุ่งเหยิงและไม่ใช่ทุกคนที่ใช้มัน

ตัวอย่างเช่นหากคุณมีรหัส__init__.pyเหมือน

import sys
if sys.version_info < (3,):
    print("Python 2 not supported")

จากนั้นโมดูลของคุณจะส่งออกsysชื่อ คุณควรเขียนแทน

import sys
if sys.version_info < (3,):
    print("Python 2 not supported")

del sys

4

เป็นตัวอย่างของสิ่งที่delสามารถใช้สำหรับฉันพบว่ามีประโยชน์ฉันสถานการณ์เช่นนี้:

def f(a, b, c=3):
    return '{} {} {}'.format(a, b, c)

def g(**kwargs):
    if 'c' in kwargs and kwargs['c'] is None:
        del kwargs['c']

    return f(**kwargs)

# g(a=1, b=2, c=None) === '1 2 3'
# g(a=1, b=2) === '1 2 3'
# g(a=1, b=2, c=4) === '1 2 4'

ทั้งสองฟังก์ชั่นที่สามารถอยู่ในแพคเกจที่แตกต่างกัน / โมดูลและโปรแกรมเมอร์ไม่จำเป็นต้องรู้ว่าสิ่งที่โต้แย้งค่าเริ่มต้นcในfจริงมี ดังนั้นโดยใช้ kwargs ร่วมกับ del คุณสามารถพูดว่า "ฉันต้องการค่าเริ่มต้นใน c" โดยการตั้งค่าเป็นไม่มี (หรือในกรณีนี้ก็ปล่อยไว้)

คุณสามารถทำสิ่งเดียวกันกับสิ่งที่ชอบ:

def g(a, b, c=None):
    kwargs = {'a': a,
              'b': b}
    if c is not None:
        kwargs['c'] = c

    return f(**kwargs)

อย่างไรก็ตามฉันพบตัวอย่างก่อนหน้านี้แห้งมากขึ้นและสง่างาม


3

เมื่อใดที่ del มีประโยชน์ใน python

x[i:i+1]=[]คุณสามารถใช้มันในการลบองค์ประกอบหนึ่งของอาร์เรย์แทนไวยากรณ์ชิ้น สิ่งนี้อาจมีประโยชน์หากคุณอยู่ในos.walkและต้องการลบองค์ประกอบในไดเรกทอรี ฉันจะไม่พิจารณาคำหลักที่มีประโยชน์สำหรับสิ่งนี้แม้ว่าจะสามารถสร้าง[].remove(index)วิธีการได้ ( .removeวิธีนี้จริง ๆ แล้วเป็นวิธีการค้นหาและลบค่าอินสแตนซ์แรกของค่า)


7
[].pop(index)[].remove(item)และ อย่าใช้ชื่อตัวแปร"index"เมื่อพูดถึงคุณค่าทำให้มันดูสับสน
สกี

@Ski ป๊อปไม่ใช้ดัชนี นี่คือคำตอบที่ถูกต้องในขณะที่ครึ่งหนึ่งของคำตอบเหล่านี้เพียงแค่ให้ตัวอย่างโดยใช้ del โดยที่ไม่มีจะทำงานเช่นกัน รายการวัตถุตั้งค่าเป็นไม่มียังคงอยู่ในรายการในขณะที่ del ลบรายการ
user5389726598465

3

ฉันพบว่าdelมีประโยชน์สำหรับการจัดการหน่วยความจำแบบหลอกด้วยตนเองเมื่อจัดการข้อมูลขนาดใหญ่ด้วย Numpy ตัวอย่างเช่น:

for image_name in large_image_set:
    large_image = io.imread(image_name)
    height, width, depth = large_image.shape
    large_mask = np.all(large_image == <some_condition>)
    # Clear memory, make space
    del large_image; gc.collect()

    large_processed_image = np.zeros((height, width, depth))
    large_processed_image[large_mask] = (new_value)
    io.imsave("processed_image.png", large_processed_image)

    # Clear memory, make space
    del large_mask, large_processed_image; gc.collect()

นี่อาจเป็นความแตกต่างระหว่างการนำสคริปต์ไปสู่การหยุดการบดเนื่องจากระบบสลับกันอย่างบ้าคลั่งเมื่อ Python GC ไม่สามารถทำงานได้และมันทำงานได้อย่างราบรื่นอย่างสมบูรณ์แบบภายใต้ขีด จำกัด หน่วยความจำที่หลวมซึ่งทำให้มีพื้นที่เหลือเฟือมากมาย และรหัสในขณะที่มันทำงาน


2

ฉันคิดว่าหนึ่งในเหตุผลที่ del มีไวยากรณ์ของตัวเองก็คือการแทนที่ด้วยฟังก์ชันอาจเป็นเรื่องยากในบางกรณีเนื่องจากมันทำงานบนการผูกหรือตัวแปรและไม่ใช่ค่าที่อ้างอิง ดังนั้นหากรุ่นฟังก์ชันของเดลถูกสร้างขึ้นบริบทจะต้องถูกส่งผ่านมา del foo จะต้องกลายเป็น globals (). ลบ ('foo') หรือคนในท้องถิ่น (). ลบ ('foo') ซึ่งทำให้ยุ่งเหยิง และอ่านได้น้อยลง ถึงกระนั้นฉันก็บอกว่าการกำจัดเดลจะดีเพราะมันใช้ยาก แต่การลบคุณสมบัติภาษา / ข้อบกพร่องอาจเจ็บปวดได้ บางทีหลาม 4 จะลบทิ้ง :)


2

ฉันต้องการอธิบายรายละเอียดของคำตอบที่ได้รับการยอมรับเพื่อเน้นความแตกต่างระหว่างการตั้งค่าตัวแปรให้Noneกับการลบออกด้วยdel:

รับตัวแปรfoo = 'bar'และนิยามฟังก์ชันต่อไปนี้:

def test_var(var):
    if var:
        print('variable tested true')
    else:
        print('variable tested false')

เมื่อประกาศครั้งแรกtest_var(foo)ผลตอบแทนvariable tested trueตามที่คาดไว้

ตอนนี้ลอง:

foo = None
test_var(foo)

variable tested falseซึ่งอัตราผลตอบแทน

ตัดพฤติกรรมนี้ด้วย:

del foo
test_var(foo)

NameError: name 'foo' is not definedซึ่งตอนนี้ยก


0

อีกช่องทางหนึ่งการใช้งาน: ในpyrootด้วย ROOT5 หรือ ROOT6 "del" อาจมีประโยชน์ในการลบวัตถุหลามที่อ้างถึงวัตถุ C ++ ที่ไม่มีอยู่แล้ว สิ่งนี้ยอมให้การค้นหา pyroot แบบไดนามิกค้นหาวัตถุ C ++ ที่มีชื่อเหมือนกันและผูกเข้ากับชื่อไพ ธ อน ดังนั้นคุณสามารถมีสถานการณ์เช่น:

import ROOT as R
input_file = R.TFile('inputs/___my_file_name___.root')
tree = input_file.Get('r')
tree.Draw('hy>>hh(10,0,5)')
R.gPad.Close()
R.hy # shows that hy is still available. It can even be redrawn at this stage.
tree.Draw('hy>>hh(3,0,3)') # overwrites the C++ object in ROOT's namespace
R.hy # shows that R.hy is None, since the C++ object it pointed to is gone
del R.hy
R.hy # now finds the new C++ object

หวังว่าช่องนี้จะถูกปิดด้วยการจัดการวัตถุของ ROOT7



-2

เมื่อฉันต้องใช้:

del serial
serial = None

เพราะใช้เท่านั้น:

serial = None

ไม่ปล่อยพอร์ตอนุกรมเร็วพอที่จะเปิดอีกครั้งในทันที จากบทเรียนนั้นฉันได้เรียนรู้สิ่งที่delมีความหมายจริง ๆ : "GC นี่เดี๋ยวนี้! และรอจนกว่ามันจะเสร็จสิ้น" และนั่นมีประโยชน์จริง ๆ ในหลาย ๆ สถานการณ์ system.gc.del_this_and_wait_balbalbalba(obj)แน่นอนคุณอาจจะมี


5
อืม ... นั่นไม่ควรสร้างความแตกต่าง แม้ว่าปัญหาของคุณอาจได้รับการแก้ไขโดยความล่าช้าเป็นพิเศษใช่หรือไม่
Winston Ewert

3
ฉันไม่คิดว่าคุณจะสามารถคืนค่าGC ได้ในตอนนี้ด้วยเอกสารใด ๆ ฉันคิดว่าการใช้ GC และการเรียกใช้__del__()นั้นมักจะผิดใน Python (ฉันไม่ทราบสาเหตุของการออกแบบนี้) และควรใช้บริบท API API ( withคำสั่ง)
Pavel Šimerda

1
นั่นคือการเขียนโปรแกรมวูดู ดูคำอธิบายวิธีการและหมายเหตุในเอกสารประกอบสำหรับวัตถุ. _ del __ ()สำหรับรายละเอียดและโปรดจำไว้ว่านี่เป็นเพียงการอธิบายการใช้งาน CPythons ปัจจุบันที่มีการนับการอ้างอิง การใช้งาน Python อื่น ๆ (การใช้ PyPy, Jython, IronPython, Brython, …) หรือการใช้งาน CPython ในอนาคตอาจใช้รูปแบบการรวบรวมขยะที่แตกต่างกัน Jython ใช้ JVMs GC ซึ่งจะไม่ลบวัตถุในทันที serialโมดูลยังทำงานร่วมกับ Jython เพื่อให้คุณสับไม่ได้ทำงานที่นั่น!
BlackJack

BTW gc.collectจะเป็นวิธีการรีไซเคิลอย่างชัดเจน รองรับการใช้งานของงูใหญ่
tdihp

-2

เดลเทียบเท่ากับ "unset" ในหลายภาษาและเป็นจุดอ้างอิงไขว้ย้ายจากภาษาอื่นเป็นไพ ธ อน .. ผู้คนมักจะมองหาคำสั่งที่ทำสิ่งเดียวกันกับที่พวกเขาเคยทำในภาษาแรก ... var ถึง "" หรือไม่มีใครไม่ลบ var ออกจากขอบเขตจริงๆ .. แต่เพียงล้างค่าของชื่อ var ตัวเองจะยังคงถูกเก็บไว้ในหน่วยความจำ ... ทำไม?!? ในสคริปต์ที่ใช้หน่วยความจำมาก .. ทิ้งขยะไว้ข้างหลังมันไม่มีอะไรเลย ... ทุกภาษามีฟังก์ชั่น var "unset / delete" รูปแบบบางอย่าง .. ทำไมไม่ใช้หลาม?


7
delไม่เรียกใช้ตัวรวบรวมขยะเร็วกว่า= Noneและจะไม่ทิ้งขยะในระยะยาว คุณอาจต้องการเก็บสะสมขยะของ Python
SilverbackNet

-3

ทุกออบเจ็กต์ในไพ ธ อนมีตัวระบุ, ประเภท, จำนวนการอ้างอิงที่สัมพันธ์กันเมื่อเราใช้ del จำนวนการอ้างอิงจะลดลงเมื่อจำนวนการอ้างอิงกลายเป็นศูนย์มันเป็นตัวเลือกที่เป็นไปได้สำหรับการรวบรวมขยะ สิ่งนี้จะแตกต่างเดลเมื่อเปรียบเทียบกับการตั้งค่าตัวระบุเป็นไม่มี ในกรณีต่อมามันก็หมายความว่าวัตถุเพิ่งจะออกจากป่า (จนกว่าเราจะออกนอกขอบเขตในกรณีที่การนับจะลดลง) และเพียงตอนนี้ตัวบ่งชี้ชี้ไปที่วัตถุอื่น ๆ (ตำแหน่งหน่วยความจำ)


3
ฉันต้องการดูข้อพิสูจน์นี้ การมอบหมายไม่มีควรลดจำนวนการอ้างอิง
Jason Baker

3
นี่เป็นเรื่องไร้สาระและตรงกันข้ามกับการเก็บขยะ (ในแง่ที่ทิ้งขยะไว้รอบ ๆ )
Pavel Šimerda
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.