Python ผสมสารป้องกันลายหรือไม่


34

ฉันรู้อย่างเต็มที่ว่าpylintและเครื่องมือวิเคราะห์แบบคงที่อื่น ๆ ไม่ได้รู้ทั้งหมดและบางครั้งคำแนะนำของพวกเขาจะต้องไม่เชื่อฟัง (ใช้กับคลาสข้อความที่หลากหลายไม่ใช่แค่conventions)


ถ้าฉันมีชั้นเรียนเช่น

class related_methods():

    def a_method(self):
        self.stack.function(self.my_var)

class more_methods():

    def b_method(self):
        self.otherfunc()

class implement_methods(related_methods, more_methods):

    def __init__(self):
        self.stack  = some()
        self.my_var = other()

    def otherfunc(self):
        self.a_method()

เห็นได้ชัดว่ามีการวางแผน นี่เป็นตัวอย่างที่ดีกว่าหากคุณต้องการ

ฉันเชื่อว่าสไตล์นี้เรียกว่าใช้ "มิกซ์"

เช่นเดียวกับเครื่องมืออื่น ๆpylintอัตรารหัสนี้ที่-21.67 / 10ส่วนใหญ่เพราะมันคิดmore_methodsและrelated_methodsไม่ได้มีselfหรือแอตทริบิวต์otherfunc, stack, annd my_varเพราะโดยไม่ต้องใช้รหัสที่มันเห็นได้ชัดว่าไม่สามารถดูrelated_methodsและมีผสมในmore_methodsimplement_methods

คอมไพเลอร์และเครื่องมือวิเคราะห์แบบสแตติกไม่สามารถแก้ปัญหาการหยุดนิ่งได้เสมอไปแต่ฉันรู้สึกว่านี่เป็นกรณีที่มองว่าสิ่งที่สืบทอดมาimplement_methodsจะแสดงให้เห็นว่าสิ่งนี้เป็นสิ่งที่ถูกต้องสมบูรณ์และนั่นก็เป็นเรื่องง่ายมาก

ทำไมเครื่องมือวิเคราะห์แบบคงที่ปฏิเสธรูปแบบ OOP ที่ถูกต้อง (ฉันคิดว่า)

ทั้ง:

  1. พวกเขาไม่แม้แต่จะลองตรวจสอบการสืบทอดหรือ

  2. มิกซ์อินถูกทำให้หมดกำลังใจใน Python ซึ่งเป็นสำนวนที่อ่านง่าย


# 1 เห็นได้ชัดว่าไม่ถูกต้องเพราะถ้าฉันขอpylintบอกฉันเกี่ยวกับคลาสของฉันที่สืบทอดมาunittest.TestCaseซึ่งใช้ self.assertEqual(สิ่งที่กำหนดไว้ในเท่านั้นunittest.TestCase) มันไม่บ่น

มิกซ์อินเป็นเสียงไพเราะหรือท้อแท้หรือไม่?


1
นี่เป็นคำถามที่ไม่ดีใช่ไหม นอกหัวข้อไหม มันตอบไม่ได้เหรอ? ฉันโง่หรือเปล่า ผู้คนสามารถ DV แต่พวกเขาไม่ต้องการที่จะช่วยปรับปรุง
แมว

1
มีบางอย่างที่น่าเบื่อที่จะมีคนถามว่า "นี่เป็นรูปแบบ (ต่อต้าน -)" หรือ "เป็น pythonic นี้ (ไม่)"

9
@MichaelT ไม่เป็นไร พวกเขาสามารถหยุดทบทวนคำถามได้
Katana314

2
@tac ผู้คนจะ downvote ด้วยเหตุผลต่าง ๆ แต่ไม่จำเป็นต้องบอกว่าทำไม - ปุ่ม downvote มีคำแนะนำเครื่องมือที่พูดว่า "คำถามนี้ไม่ได้แสดงความพยายามในการวิจัยใด ๆ มันไม่ชัดเจนหรือไม่มีประโยชน์" - คลุมเครือถ้า คำตอบที่ยอมรับได้ 8 ขึ้นไปและลดลง 1 อันที่จริงแล้วค่อนข้างดีโดยเฉพาะกับคำถามที่ downvotes นั้นฟรี อย่าปล่อยให้มันทำให้คุณผิดหวัง ไชโย
Aaron Hall

@AaronHall ฉันรู้ว่าคนที่ได้รับอนุญาตให้ทำสิ่งที่พวกเขาชอบด้วยการลงคะแนนของพวกเขาแน่นอนฉันบอกผู้ใช้ใหม่ที่บ่นในสิ่งเดียวกัน
แมว

คำตอบ:


16

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

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


ใช่มันเป็นสิ่งที่พระเจ้าฉันยอมรับ ในกรณีนี้ฉันจะเถียงว่าซีพียูนั้นจะเป็นวัตถุเทพเจ้า
แมว

15

ฉันเชื่อว่า Mixins สามารถเป็น Pythonic ได้อย่างแน่นอน อย่างไรก็ตามวิธีที่เป็นสำนวนในการปิดเสียงรบกวนของคุณ - และปรับปรุงการอ่านของ Mixins ของคุณ - คือทั้ง (1) กำหนดวิธีการแบบนามธรรมที่กำหนดวิธีการที่ลูก ๆ ของ Mixin ต้องนำมาใช้อย่างชัดเจนและ (2) กำหนดไว้ล่วงหน้าNone- ค่าฟิลด์สำหรับสมาชิกข้อมูล Mixin ที่ลูกต้องเริ่มต้น

ใช้รูปแบบนี้กับตัวอย่างของคุณ:

from abc import ABC, abstractmethod


class related_methods():
    my_var = None
    stack = None

    def a_method(self):
        self.stack.function(self.my_var)


class more_methods(ABC):
    @abstractmethod
    def otherfunc(self):
        pass

    def b_method(self):
        self.otherfunc()


class implement_methods(related_methods, more_methods):
    def __init__(self):
        self.stack  = some()
        self.my_var = other()

    def otherfunc(self):
        self.a_method()

2
+1 สำหรับคำตอบของคุณถึงแม้ว่าabstract other(self): passสิ่งที่แลกเปลี่ยนความสับสนของ linter สำหรับเหมือง
cat

มันสับสนมากขึ้นโดยไม่ต้องใช้ @abstractmethod ;-) ฉันเริ่มต้นด้วย Java ก่อนดังนั้นนี่ก็ดีสำหรับฉัน
Chris Huang-Leaver

9

ฉันคิดว่ามิกซ์อินนั้นดี แต่ฉันก็คิดว่าไพลินมีสิทธิ์ในกรณีนี้ คำเตือน: สิ่งตามความคิดเห็นดังต่อไปนี้

คลาสดีมิกซ์อินรวมอยู่ด้วยมีความรับผิดชอบชัดเจน โดยอุดมคติแล้วมิกซ์อินควรมีสถานะทั้งหมดที่เข้าถึงได้และตรรกะในการจัดการ เช่นมิกซ์อินที่ดีสามารถเพิ่มlast_updatedฟิลด์ลงในคลาสโมเดล ORM จัดเตรียมตรรกะสำหรับการตั้งค่าและวิธีการค้นหาเร็กคอร์ดที่เก่าที่สุด / ใหม่ที่สุด

การอ้างถึงสมาชิกอินสแตนซ์ที่ไม่ได้ประกาศ (ตัวแปรและวิธีการ) จะดูแปลก ๆ

วิธีการที่เหมาะสมมากขึ้นอยู่กับงานในมือ

มันอาจจะเป็นมิกซ์อินที่มีบิตของสถานะที่เกี่ยวข้องเก็บไว้ในนั้น

มันอาจเป็นลำดับชั้นของชั้นที่แตกต่างกันซึ่งวิธีการที่คุณแจกจ่ายในปัจจุบันผ่าน mixin อยู่ในชั้นฐานในขณะที่ความแตกต่างในการใช้งานในระดับที่ต่ำกว่าอยู่ในคลาสย่อย สิ่งนี้ดูเหมาะสมที่สุดสำหรับกรณีของคุณด้วยการดำเนินการสแต็ก

อาจเป็นมัณฑนากรระดับที่เพิ่มวิธีการหรือสอง; เรื่องนี้มักจะสมเหตุสมผลเมื่อคุณต้องผ่านการขัดแย้งกับมัณฑนากรเพื่อส่งผลกระทบต่อการสร้างวิธีการ

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


6

linter ไม่ทราบว่าคุณใช้คลาสเป็น mixin ไพลินทราบว่าคุณใช้มิกซ์อินถ้าคุณเพิ่มคำต่อท้าย 'มิกซ์อิน' หรือ 'มิกซ์อิน' ที่ท้ายชื่อคลาสจากนั้นตัวหยุดจะหยุดบ่น

linter_without_mixins linter2_with_mixin

มิกซ์อินไม่ดีหรือไม่ดีต่อกันเป็นเพียงเครื่องมือ คุณทำให้พวกเขาใช้งานได้ดีหรือใช้งานไม่ดี


2
อ่านความคิดเห็นเพิ่มเติมได้ที่นี่ดูวิธีการตอบ
gnat

2
นี่เป็นคำตอบที่มีค่าเพราะฉันไม่คิดว่าฉันจะรู้เกี่ยวกับคำใบ้นั้นเป็นอย่างอื่น
cat

1

mixins โอเคไหม

Python ผสมสารป้องกันลายหรือไม่

มิกซ์อินไม่ได้ท้อแท้ - เป็นกรณีใช้งานที่ดีสำหรับการรับมรดกหลายครั้ง

ทำไมคุณถึงบ่นถึง?

pylint จะเห็นได้ชัดบ่นเพราะไม่ทราบว่าotherfunc, stackและmy_var มาจาก

จิ๊บจ๊อย?

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

201
202 class OpCore():
203     # nothing runs without these
204
205 class OpLogik(): 
206     # logic methods... 
207 
208 class OpString(): 
209     # string things
210 
211 
212 class Stack(OpCore, OpLogik, OpString): 
213 
214     "the mixin mixer of the above mixins" 

ค่าใช้จ่ายของมิกซ์อินและเสียงรบกวน

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

ข้อสรุป

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


มีเหตุผลที่ดีที่จะแยกพวกเขาออกจากตัวอย่างที่เชื่อมโยงและไม่เกี่ยวข้อง - มันง่ายกว่าที่ฉันจะจัดระเบียบโค้ดของฉันเมื่อฉันมีเศษส่วนของคลาสเต็มที่ใช้คณิตศาสตร์อีกตัวที่ใช้สตริง เพื่อรับ Forth Soup
แมว

"ค่าใช้จ่ายอีกอย่างก็คือคุณต้องแยกรหัสของคุณออกเป็นเนมสเปซที่แตกต่างกันซึ่งอาจทำให้ยากสำหรับโปรแกรมเมอร์ในการค้นหาความหมายของ" - ไม่นั่นไม่ใช่กรณีทั้งหมด คลาสเนมสเปซทำให้ง่ายต่อการบอกว่ากลุ่มของวิธีการทำอะไรและเมื่อใครบางคนต้องการใช้สแต็คพวกเขาควรโทร / ใช้ซุปฟอร์ทไม่ใช่ส่วนผสมแต่ละตัว
cat

@cat อาจเป็นเพราะพวกมันถูกสร้างขึ้นมาและไม่ได้ใช้ในโครงการขนาดใหญ่จริง ๆ ยกตัวอย่างเช่นไม่สนับสนุนคะแนนของคุณในการใช้มิกซ์อิน ทั้งสองแสดงเพียงครั้งเดียวที่มีการใช้มิกซ์อินซึ่งในกรณีนี้เพียงแค่นำการติดตั้งไปใช้ในที่เดียวคือรูปแบบและองค์กรที่ดีกว่า ตอนนี้ถ้าคุณสามารถแสดงเคสที่คุณต้องการคุณสมบัติทั่วไปในคลาสต่างๆ แต่ไม่ต้องการคลาสพื้นฐานทั่วไปนั่นคือที่ที่คุณจะใช้ Mixin ซึ่งอยู่ข้างๆคำถามที่เป็นขุยของคุณ (UltraBird ตอบว่าอย่างนั้น) แต่นี่ตอบคำถามของคุณโดยทั่วไปเกี่ยวกับการบังคับใช้มิกซ์อิน
dlamblin
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.