portaldacalheta.pt
  • หลัก
  • การเพิ่มขึ้นของระยะไกล
  • ผู้คนและทีมงาน
  • การวางแผนและการพยากรณ์
  • การออกแบบ Ux
ส่วนหลัง

เป็น Python 3 และกลับมาอีกครั้ง: คุ้มกับการเปลี่ยนหรือไม่?



Python 3 มีมาเจ็ดปีแล้ว แต่บางคนก็ยังชอบใช้ Python 2 แทนเวอร์ชันที่ใหม่กว่า นี่เป็นปัญหาโดยเฉพาะอย่างยิ่งสำหรับ neophytes ที่เข้าใกล้ Python เป็นครั้งแรก ฉันรู้เรื่องนี้ในที่ทำงานก่อนหน้านี้กับเพื่อนร่วมงานในสถานการณ์เดียวกัน ไม่เพียง แต่พวกเขาไม่รู้ถึงความแตกต่างระหว่างสองเวอร์ชัน แต่ยังไม่ทราบถึงเวอร์ชันที่ติดตั้ง

อย่างหลีกเลี่ยงไม่ได้เพื่อนร่วมงานต่างก็ติดตั้งล่ามรุ่นต่างๆ นั่นเป็นสูตรสำหรับหายนะหากตอนนั้นพวกเขาพยายามแบ่งปันสคริปต์ระหว่างกันแบบสุ่มสี่สุ่มห้า



นี่ไม่ใช่ความผิดของพวกเขาในทางตรงกันข้าม จำเป็นต้องใช้ความพยายามมากขึ้นในการจัดทำเอกสารและสร้างความตระหนักเพื่อขจัดสิ่งปกคลุมของ FUD (ความกลัวความไม่แน่นอนและความสงสัย) ที่ส่งผลต่อการเลือกของเรา โพสต์นี้เป็นแนวคิดสำหรับพวกเขาหรือสำหรับผู้ที่ใช้ Python 2 อยู่แล้ว แต่ไม่แน่ใจเกี่ยวกับการย้ายไปยังเวอร์ชันถัดไปอาจเป็นเพราะพวกเขาลองใช้เวอร์ชัน 3 ในช่วงเริ่มต้นเมื่อมีการปรับปรุงน้อยลงและการรองรับไลบรารีก็แย่ลง



ภาษาสองภาษาหนึ่งภาษา

ก่อนอื่นจริงไหมที่ Python 2 และ Python 3 เป็นภาษาที่แตกต่างกัน? นี่ไม่ใช่คำถามเล็กน้อย แม้ว่าบางคนจะตั้งคำถามว่า: “ ไม่ไม่ใช่ภาษาใหม่” , ที่จริงแล้ว ข้อเสนอหลายอย่างที่อาจทำให้ความเข้ากันไม่ได้โดยไม่ได้รับข้อได้เปรียบที่สำคัญถูกปฏิเสธ .



Python 3 เป็น Python เวอร์ชันใหม่ แต่ไม่จำเป็นต้องทำงานร่วมกับโค้ดที่เขียนขึ้นสำหรับ Python 2 ในขณะเดียวกันก็สามารถเขียนโค้ดที่เข้ากันได้กับทั้งสองเวอร์ชันและนี่ไม่ใช่โดยบังเอิญ แต่เป็นความมุ่งมั่นที่ชัดเจนของ นักพัฒนา Python ที่ร่าง PEP (Python Extension Proposal) หลายฉบับ ในบางกรณีที่ไวยากรณ์เข้ากันไม่ได้เนื่องจาก Python เป็นภาษาที่เราสามารถแก้ไขโค้ดแบบไดนามิกในขณะรันไทม์ เราสามารถแก้ปัญหาได้ โดยไม่ต้องอาศัยตัวประมวลผลล่วงหน้าที่มีไวยากรณ์ต่างจากภาษาที่เหลือโดยสิ้นเชิง

ดังนั้นไวยากรณ์จึงไม่มีปัญหา (โดยเฉพาะการละเว้นเวอร์ชันของ Python 3 ก่อน 3.3) ความแตกต่างที่สำคัญอื่น ๆ คือพฤติกรรมของโค้ดความหมายและการมี / ไม่มีไลบรารีขนาดใหญ่สำหรับหนึ่งในสองเวอร์ชันเท่านั้น นี่เป็นปัญหาสำคัญ แต่ก็ไม่ใช่เรื่องแปลกใหม่สำหรับผู้ที่มีประสบการณ์กับภาษาโปรแกรมอื่น ๆ อยู่แล้ว คุณอาจได้รับโค้ดเบส / ไลบรารีเก่าที่ไม่สามารถสร้างด้วยเวอร์ชันล่าสุดของคอมไพเลอร์เดียวกันที่ใช้ในตอนแรก เป็นตัวคอมไพเลอร์เองในกรณีเหล่านี้ที่จะช่วยคุณได้ (ใน Python ความช่วยเหลือจะมาจากชุดทดสอบของคุณเอง)



ทำไมถึงทำให้เวอร์ชันใหม่แตกต่างกัน? การเปลี่ยนแปลงเหล่านี้จะทำให้เราได้เปรียบอะไรบ้าง?

ตัวอย่างที่เป็นรูปธรรม

สมมติว่าเราต้องการเขียนโปรแกรมเพื่ออ่านเจ้าของไฟล์ / ไดเรกทอรี (บนระบบ Unix) ในไดเร็กทอรีปัจจุบันของเราและพิมพ์บนหน้าจอ



# encoding: utf-8 from os import listdir, stat # to keep this example simple, we won't use the `pwd` module names = {1000: 'dario', 1001: u'олга'} for node in listdir(b'.'): owner = names[stat(node).st_uid] print(owner + ': ' + node)

ทุกอย่างทำงานถูกต้องหรือไม่? เห็นได้ชัดว่ามันไม่ เราระบุการเข้ารหัสสำหรับไฟล์ที่มีซอร์สโค้ดหากเรามีไฟล์ที่สร้างโดยолга (uid 1001) ในไดเร็กทอรีของเราชื่อของเราจะถูกพิมพ์อย่างถูกต้องและแม้ว่าเราจะมีไฟล์ที่มีชื่อที่ไม่ใช่ ASCII สิ่งเหล่านี้ก็จะถูกพิมพ์อย่างถูกต้อง .

ยังมีบางกรณีที่เรายังไม่ได้กล่าวถึงนั่นคือไฟล์ที่สร้างโดยолга AND ที่มีอักขระที่ไม่ใช่ ASCII ในชื่อ ...



su олга -c 'touch é'

มาลองเปิดตัวสคริปต์เล็ก ๆ ของเราอีกครั้งและเราจะได้รับ:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)

หากคุณคิดเกี่ยวกับเรื่องนี้สถานการณ์ที่คล้ายกันอาจเป็นเรื่องที่น่ารังเกียจ: คุณเขียนโปรแกรมของคุณ (ยาวเป็นพัน ๆ บรรทัดแทนที่จะเป็น 4 ตัวอย่างนี้) คุณเริ่มรวบรวมผู้ใช้บางคนบางคนมาจากประเทศที่ไม่ได้พูดภาษาอังกฤษด้วยซ้ำ ด้วยชื่อที่แปลกใหม่กว่า ทุกอย่างเรียบร้อยดีจนกว่าผู้ใช้คนใดคนหนึ่งจะตัดสินใจสร้างไฟล์ที่ผู้ใช้ที่มีชื่อธรรมดามากกว่าสามารถสร้างได้โดยไม่มีปัญหา ตอนนี้โค้ดของคุณเกิดข้อผิดพลาดเซิร์ฟเวอร์อาจตอบทุกคำขอจากผู้ใช้รายนี้ด้วยข้อผิดพลาด 500 และคุณจะต้องขุดใน codebase เพื่อทำความเข้าใจว่าเหตุใดจึงเกิดข้อผิดพลาดเหล่านี้ขึ้น



Python 3 ช่วยเราได้อย่างไร? หากคุณพยายามเรียกใช้สคริปต์เดียวกันคุณจะพบว่า Python สามารถตรวจจับได้ทันทีเมื่อคุณกำลังดำเนินการปฏิบัติการที่เป็นอันตราย แม้ว่าจะไม่มีไฟล์ที่มีชื่อแปลก ๆ และ / หรือสร้างโดยผู้ใช้แปลก ๆ คุณจะได้รับข้อยกเว้นทันทีเช่น:

`TypeError: Can't convert 'bytes' object to str implicitly`

เกี่ยวข้องกับ line:



print(owner + ': ' + node)

ข้อความแสดงข้อผิดพลาดนั้นเข้าใจง่ายกว่าในความคิดของฉัน วัตถุ str คือ owner และ node เป็นวัตถุไบต์ เมื่อทราบสิ่งนี้เห็นได้ชัดว่าปัญหาเกิดจาก listdir กำลังส่งคืนรายการวัตถุไบต์ให้เรา

รายละเอียดที่ทุกคนไม่ทราบคือ listdir ส่งคืนรายการไบต์อ็อบเจ็กต์หรือสตริง Unicode ขึ้นอยู่กับชนิดของอ็อบเจ็กต์ที่ใช้เป็นอินพุต ฉันหลีกเลี่ยงการใช้ listdir('.') เพื่อให้ได้พฤติกรรมเดียวกันใน Python 2 และ Python 3 มิฉะนั้นใน Python 3 สิ่งนี้จะเป็นสตริง Unicode ที่จะทำให้จุดบกพร่องหายไป

หากเราพยายามเปลี่ยนอักขระเดี่ยวจาก listdir(b'.') ถึง listdir(u'.') เราจะสามารถดูว่าโค้ดทำงานอย่างไรใน Python 3 และ Python 2 เพื่อความสมบูรณ์เราควรเปลี่ยน 'dario' ถึง u'dario'.

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

ในความคิดของฉันสถานการณ์นี้เป็นสัญลักษณ์ของ maxim:“ ตัวแยกสามารถแยกเป็นก้อนได้ง่ายกว่าที่จะแยกก้อนได้” สิ่งที่รวมเข้าด้วยกันใน Python 2 (สตริงยูนิโคดและสตริงเริ่มต้นของไบต์ซึ่งสามารถบังคับเข้าด้วยกันได้อย่างอิสระ) ได้ถูกแบ่งออกใน Python 3

เครื่องมือสำหรับการแปลงอัตโนมัติ

ด้วยเหตุนี้เครื่องมือเช่น 2 ถึง 3 แม้ว่าจะเขียนได้ดีและมีประโยชน์อย่างยิ่งในการแปลงความแตกต่างอื่น ๆ โดยอัตโนมัติ แต่ก็มีข้อ จำกัด บางประการ ด้วยไบต์ / ยูนิโคดจะแยกความแตกต่างของพื้นผิวลักษณะการทำงานที่รันไทม์และเครื่องมือที่ทำได้เฉพาะการวิเคราะห์ / วิเคราะห์แบบคงที่จึงไม่สามารถช่วยคุณได้หากคุณมีโค้ดเบส Python 2 ขนาดใหญ่ที่ผสมทั้งสองประเภทนี้ คุณจะต้องพับแขนเสื้อขึ้นและออกแบบ API ของคุณอย่างถูกต้องเพื่อตัดสินใจว่าฟังก์ชันที่จนถึงตอนนี้ได้รับการยอมรับตามอำเภอใจของสตริงประเภทใดควรใช้งานได้กับสตริงบางส่วนเท่านั้น (และประเภทใด) ในทางกลับกันแม้ว่าจะมีการใช้งานน้อยลงมาก แต่เครื่องมือในการแปลงจาก Python 3 เป็น Python 2 ก็มีชีวิตที่ง่ายขึ้นมาก ลองดูตัวอย่าง:

เมื่อไม่นานมานี้ฉันเขียนไฟล์ เซิร์ฟเวอร์ HTTP ของเล่น (การพึ่งพาเท่านั้น: งูหลามเวทมนตร์ ) และนี่คือเวอร์ชันสำหรับ Python 2 (แปลงจาก Python 3 โดยอัตโนมัติโดยไม่จำเป็นต้องเปลี่ยนแปลงด้วยตนเอง): https://gist.github.com/berdario/8abfd9020894e72b310a

ตอนนี้หากคุณต้องการคุณสามารถดูได้โดยตรงที่ไฟล์ แปลงรหัสเป็น Python 3 ด้วย 2to3 หรือคุณสามารถแปลงโดยตรงบนระบบของคุณ เมื่อพยายามดำเนินการคุณจะทราบว่าข้อผิดพลาดทั้งหมดที่คุณสามารถพยายามแก้ไขด้วยมือนั้นเกี่ยวข้องกับการแยกไบต์ / ยูนิโคดอย่างไร

คุณสามารถใช้การเปลี่ยนแปลงดังต่อไปนี้ได้ด้วยตนเอง: https://gist.github.com/berdario/34370a8bc39895cae139/revisions

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

หากคุณสงสัยคุณสามารถลองแปลงรหัสนี้ที่คุณเพิ่งนำไปยัง Python 3 กลับไปเป็น Python 2 โดยใช้ 3 ถึง 2 คุณจะได้รับสิ่งนี้: https://gist.github.com/berdario/cbccaf7f36d61840e0ed . ซึ่งการเปลี่ยนแปลงเดียวที่ต้องใช้ด้วยตนเองคือ .encode('utf-8') ที่บรรทัด 55

เริ่มจาก Python 3 (หากคุณจำเป็นต้องแปลงกลับเป็น Python 2) มันง่ายกว่ามาก แต่ถ้าคุณต้องการให้โค้ดของคุณทำงานในเวอร์ชันอื่นการแปลงแบบสมบูรณ์แบบนี้ไม่ใช่ทางเลือกที่ดีที่สุด การรักษาความเข้ากันได้กับทั้งสองเวอร์ชันจะดีกว่ามาก Python . ในการทำเช่นนั้นคุณสามารถพึ่งพาเครื่องมือเช่น อนาคต .

Python 3 ไม่ใช่แค่เกี่ยวกับ Unicode

แม้ว่าคุณจะไม่มีโอกาสใช้ Python 3 ในการผลิต (อาจเป็นหนึ่งในไลบรารีที่คุณใช้อยู่มีขนาดใหญ่และเข้ากันได้กับ Python 2 เท่านั้น) ฉันขอแนะนำให้คุณรักษารหัสให้เข้ากันได้กับ Python 3 คุณสามารถทำได้ ต้นขั้ว / เยาะเย้ย ออกจากไลบรารีที่เข้ากันไม่ได้เพื่อให้คุณสามารถทำงานได้อย่างต่อเนื่อง การทดสอบของคุณทั้งสองเวอร์ชัน . สิ่งนี้จะช่วยให้คุณง่ายขึ้นเมื่อในอนาคตคุณพร้อมที่จะย้ายไปยัง Python 3 ในที่สุดโดยไม่ต้องพูดถึงว่าจะช่วยคุณในการออกแบบ API ของคุณให้ดีขึ้นได้อย่างไรหรือระบุข้อผิดพลาดเช่นในตัวอย่างตอนต้นนี้ โพสต์

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

หลังจากผ่านไป 5 ปีนับจากการเปิดตัว Python 2 เวอร์ชันรองสุดท้ายมีเกร็ดน่ารู้ที่น่าสนใจมากมายที่สะสมอยู่ ตัวอย่างเช่นฉันพบว่าตัวเองพึ่งพาสิ่งใหม่ ๆ ค่อนข้างบ่อย อาร์กิวเมนต์คำหลักเท่านั้น .

อาร์กิวเมนต์คำหลักที่เป็นทางเลือก

เมื่อฉันต้องการเขียนฟังก์ชันเพื่อรวมพจนานุกรมเข้าด้วยกันโดยพลการ (คล้ายกับสิ่งที่ dict.update ทำ แต่ไม่มีการแก้ไขอินพุต) ฉันพบว่าการเพิ่มอาร์กิวเมนต์ของฟังก์ชันเป็นเรื่องปกติเพื่อให้ผู้เรียกปรับแต่งตรรกะ วิธีนี้สามารถเรียกใช้ฟังก์ชันนี้ได้ดังต่อไปนี้เพื่อรวมพจนานุกรมหลาย ๆ พจนานุกรมโดยการรักษาค่าในคำสั่งขวาสุด

merge_dicts({'a':1, 'c':3}, {'a':4, 'b':2}, {'b': -1}) # {'b': -1, 'a': 4, 'c': 3}

ในทำนองเดียวกันในการผสานโดยการเพิ่มค่า:

from operator import add merge_dicts({'a':1, 'c':3}, {'a':4, 'b':2}, {'b': -1}, withf=add) # {'b': 1, 'a': 5, 'c': 3}

การใช้ API ดังกล่าวใน Python 2 จะต้องกำหนด a **kwargs ป้อนข้อมูลและค้นหา withf การโต้เถียง. หากผู้โทรพิมพ์อาร์กิวเมนต์ผิดเป็น (เช่น) withfun ข้อผิดพลาดจะถูกเพิกเฉย ใน Python 3 แทนที่จะเพิ่มอาร์กิวเมนต์ที่เป็นทางเลือกหลังจากอาร์กิวเมนต์ตัวแปร (และจะใช้ได้เฉพาะกับคีย์เวิร์ดเท่านั้น):

def second(a, b): return b def merge_dicts(*dicts, withf=second): newdict = {} for d in dicts: shared_keys = newdict.keys() & d.keys() newdict.update({k: d[k] for k in d.keys() - newdict.keys()}) newdict.update({k: withf(newdict[k], d[k]) for k in shared_keys}) return newdict

กำลังแกะกล่อง

ตั้งแต่ Python 3.5 การผสานแบบไร้เดียงสาสามารถทำได้จริงกับไฟล์ ตัวดำเนินการแกะใหม่ . แต่ก่อนหน้า 3.5 Python จะมีรูปแบบการแกะที่ดีขึ้น:

a, b, *rest = [1, 2, 3, 4, 5] rest # [3, 4, 5]

สิ่งนี้มีให้เราตั้งแต่ 3.0 Akin ในการทำลายโครงสร้างการคลายประเภทนี้เป็นรูปแบบที่ จำกัด / เฉพาะกิจของการจับคู่รูปแบบที่ใช้กันทั่วไปในภาษาที่ใช้งานได้ (ซึ่งใช้สำหรับการควบคุมการไหลด้วย) และเป็นคุณลักษณะทั่วไปในภาษาไดนามิกเช่น Ruby และ Javascript (ซึ่งการสนับสนุน สำหรับ EcmaScript 2015 พร้อมใช้งาน)

ขับ uber vs lyft 2016

API ที่ง่ายกว่าสำหรับ Iterables

ใน Python 2 API จำนวนมากที่จัดการกับ iterables ซ้ำกันและค่าเริ่มต้นมีความหมายที่เข้มงวด ตอนนี้ทุกอย่างจะสร้างค่าตามต้องการแทน: zip(), dict.items(), map(), range(). คุณต้องการเขียน enumerate ในเวอร์ชันของคุณเองหรือไม่ ใน Python 3 นั้นง่ายพอ ๆ กับการเขียนฟังก์ชันจากไลบรารีมาตรฐานเข้าด้วยกัน:

zip(itertools.count(1), 'abc')

เทียบเท่ากับ enumerate('abc', 1).

คำอธิบายประกอบของฟังก์ชัน

คุณไม่ต้องการกำหนด HTTP API แบบง่ายๆเช่นนี้หรือ

@get('/balance') def balance(user_id: int): pass from decimal import Decimal @post('/pay') def pay(user_id: int, amount: Decimal): pass

ไม่มีอีกแล้ว '' ad-hoc syntax และความสามารถในการใช้ type / constructor (เช่น Decimal) ภายในเส้นทางของคุณโดยไม่ต้องกำหนดตัวแปลงของคุณเอง

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

ห่อ

นี่เป็นเพียงตัวอย่างง่ายๆสองสามตัวอย่าง แต่การปรับปรุงนั้นยังไปได้ไกลและท้ายที่สุดก็ช่วยคุณในการเขียนโค้ดที่มีประสิทธิภาพมากขึ้น ตัวอย่างคือการย้อนกลับห่วงโซ่ข้อยกเว้นที่เปิดใช้งานโดยค่าเริ่มต้นซึ่งแสดงในโพสต์ที่มีชื่อ aptly “ คุณลักษณะที่มีการประเมินต่ำที่สุดใน Python 3” โดย Ionel Cristian Mărieș ซึ่งกล่าวถึงในเรื่องนี้ด้วย โพสต์อื่น ๆ โดย Aaron Maxwell ร่วมกับความหมายการเปรียบเทียบที่เข้มงวดขึ้นของ Python 3 และใหม่ super พฤติกรรม.

นี่ไม่ใช่ทั้งหมด มี การปรับปรุงอื่น ๆ อีกมากมาย นี่คือสิ่งที่ฉันรู้สึกว่ามีผลกระทบมากที่สุดในแต่ละวัน:

  • ขณะนี้ฟังก์ชัน / ตัวสร้างหลายรายการกลับมา ผู้จัดการบริบท ทำให้การปิดออบเจ็กต์ง่ายขึ้นและจัดการข้อผิดพลาด: gzip.open (จาก 2.7) mmap , ThreadPoolExecutor , memoryview , FTP , TarFile , socket.create_connection , epoll , NNTP , SMTP , aifc.open , ชั้นวางของ , และอื่น ๆ.
  • lzma สำหรับการบีบอัดที่ดีขึ้นเมื่อเทียบกับ gzip
  • asyncio สำหรับการเขียนโปรแกรมแบบอะซิงโครนัสใน Python
  • pathlib ซึ่งเป็นวิธีที่ยิ่งใหญ่และแสดงออกมากขึ้นในการจัดการเส้นทาง
  • ที่อยู่ IP
  • lru_cache เพื่อแคชผลลัพธ์ของฟังก์ชันราคาแพงโดยอัตโนมัติ
  • จำลอง (โมดูลเดียวกันที่กล่าวถึงข้างต้นก่อนหน้านี้มีให้เฉพาะใน PyPI)
  • มีประสิทธิภาพมากขึ้น การแสดงสตริง ในความทรงจำ
  • สั่งซื้อ ทุกคนต้องการมันอย่างน้อยหนึ่งครั้ง
  • การเติมข้อความอัตโนมัติภายใน pdb
  • ไดเร็กทอรี __pycache__ ที่ช่วยหลีกเลี่ยงการทิ้งโฟลเดอร์โครงการอื่น ๆ ทั้งหมดด้วย .pyc ไฟล์

สามารถรับภาพพาโนรามาที่ละเอียดยิ่งขึ้นได้ด้วยไฟล์ “ มีอะไรใหม่” หน้าเอกสารหรือสำหรับภาพรวมอื่น ๆ ของการเปลี่ยนแปลงฉันขอแนะนำสิ่งนี้ด้วย โพสต์ โดย Aaron Maxwell และสิ่งเหล่านี้ สไลด์ จาก Brett Cannon

รองรับ Python 2.7 จนถึงปี 2020 แต่อย่ารอถึงปี 2020 เพื่อเปลี่ยนไปใช้เวอร์ชันใหม่ (และดีกว่า)!

ที่เกี่ยวข้อง: รูปแบบการออกแบบ Python: สำหรับโค้ดที่เพรียวบางและทันสมัย

คู่มือ Oracle เป็น SQL Server และ SQL Server ไปยัง Oracle Migration - Pt. 3

วิทยาศาสตร์ข้อมูลและฐานข้อมูล

คู่มือ Oracle เป็น SQL Server และ SQL Server ไปยัง Oracle Migration - Pt. 3
การดึงข้อมูลเก่าขณะตรวจสอบความถูกต้องด้วย React Hooks: คำแนะนำ

การดึงข้อมูลเก่าขณะตรวจสอบความถูกต้องด้วย React Hooks: คำแนะนำ

เทคโนโลยี

โพสต์ยอดนิยม
ความจริงเสมือนในอุตสาหกรรมยานยนต์
ความจริงเสมือนในอุตสาหกรรมยานยนต์
วิธีใช้ Bootstrap และสร้าง. NET Projects
วิธีใช้ Bootstrap และสร้าง. NET Projects
วิธีทำความเข้าใจและประเมินการลงทุนในกองทุนอสังหาริมทรัพย์ส่วนบุคคล
วิธีทำความเข้าใจและประเมินการลงทุนในกองทุนอสังหาริมทรัพย์ส่วนบุคคล
4 ไปวิจารณ์ภาษา
4 ไปวิจารณ์ภาษา
ข้อมูลเบื้องต้นเกี่ยวกับ Magento: การนำทางในระบบนิเวศอีคอมเมิร์ซยอดนิยม
ข้อมูลเบื้องต้นเกี่ยวกับ Magento: การนำทางในระบบนิเวศอีคอมเมิร์ซยอดนิยม
 
วีซ่า H-1B: การเดินทางของนักพัฒนา iOS จากฮอนดูรัสไปยัง Silicon Valley
วีซ่า H-1B: การเดินทางของนักพัฒนา iOS จากฮอนดูรัสไปยัง Silicon Valley
ข้อผิดพลาดทั่วไปในการสื่อสารกับลูกค้า: จะไม่ทำให้ลูกค้าของคุณผิดหวังได้อย่างไร
ข้อผิดพลาดทั่วไปในการสื่อสารกับลูกค้า: จะไม่ทำให้ลูกค้าของคุณผิดหวังได้อย่างไร
การออกแบบที่คาดหวัง: วิธีสร้างประสบการณ์ผู้ใช้ที่มีมนต์ขลัง
การออกแบบที่คาดหวัง: วิธีสร้างประสบการณ์ผู้ใช้ที่มีมนต์ขลัง
กราฟิก 3 มิติ: บทช่วยสอน WebGL
กราฟิก 3 มิติ: บทช่วยสอน WebGL
การออกแบบ VUI - Voice User Interface
การออกแบบ VUI - Voice User Interface
โพสต์ยอดนิยม
  • อินเทอร์เน็ตของอุปกรณ์ภายในบ้าน
  • วิธีการทำงานของทับทิมบนราง
  • เทมเพลตเอกสารการออกแบบระดับต่ำ
  • หน้าจอ @media และ (ความกว้างสูงสุด 480px)
  • ความแตกต่างระหว่าง s corp และ c corp llc
  • รูปแบบสัญญาการลงทุน
หมวดหมู่
  • การเพิ่มขึ้นของระยะไกล
  • ผู้คนและทีมงาน
  • การวางแผนและการพยากรณ์
  • การออกแบบ Ux
  • © 2022 | สงวนลิขสิทธิ์

    portaldacalheta.pt