วิธีและตำแหน่งที่จะคำนวณตัวแปรอินสแตนซ์ที่ได้รับใน python

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

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

แก้ไข: นี่เป็นตัวอย่างง่ายๆของสิ่งที่ฉันหมายถึง:

class Amendment:

    def __init__(self, string):
        self.string = string
        self.atoms = generate_atoms()


    def generate_atoms():
        return do_something_that_takes_long(self.string)

person Neil    schedule 20.05.2018    source แหล่งที่มา
comment
คุณมีแนวโน้มที่จะได้รับความช่วยเหลือมากขึ้นหากคุณโพสต์ตัวอย่างเล็กๆ น้อยๆ เพื่อให้เราทราบอย่างชัดเจนว่าคุณสร้างคลาสนี้อย่างไร (เราไม่จำเป็นต้องดูรายละเอียดของอัลกอริธึมการสร้างอะตอมจริงของคุณ เวอร์ชันที่เรียบง่ายก็เพียงพอแล้ว) . และด้วยวิธีนี้เราสามารถใช้ชื่อแอตทริบิวต์จากโค้ดของคุณ แทนที่จะต้องพูดถึงตัวแปรอินสแตนซ์ตัวแรก ฯลฯ   -  person PM 2Ring    schedule 20.05.2018
comment
ในระหว่างนี้ ตัวแปรอินสแตนซ์แรกมีการเปลี่ยนแปลงตลอดอายุของอินสแตนซ์หรือไม่   -  person PM 2Ring    schedule 20.05.2018
comment
แก้ไขแล้ว และไม่ ตัวแปรอินสแตนซ์แรกจะไม่ถูกเปลี่ยนแปลง ดังนั้นการคำนวณอะตอมจึงเกิดขึ้นได้ครั้งเดียวแล้วคงอยู่ในวัตถุนั้นตลอดไป   -  person Neil    schedule 20.05.2018
comment
ขอบคุณ. คุณต้องการให้ทั้ง .string และ .atoms เป็นคุณสมบัติแบบรับอย่างเดียวใช่ไหม   -  person PM 2Ring    schedule 20.05.2018
comment
ใช่ .string จะเป็น poperty ที่ได้รับเท่านั้น   -  person Neil    schedule 20.05.2018


คำตอบ (1)


คุณลืม self ไว้สองสามแห่ง แต่นี่คือวิธีสร้างคุณสมบัติ .string และ .atoms แบบรับอย่างเดียว เราใช้แอตทริบิวต์ "private" สองสามรายการที่ถูกสร้างขึ้น ในช่วง __init__ และใช้ @property เพื่อสร้าง getters จริง

class Amendment:
    def __init__(self, string):
        self._string = string
        self._atoms = self.generate_atoms()

    def generate_atoms(self):
        #return do_something_that_takes_long(self.string)
        return list(self.string)

    @property
    def string(self):
        return self._string

    @property
    def atoms(self):
        return self._atoms

# Test

a = Amendment('abc')
print(a.string, a.atoms)
# This will raise an error because `.string` is a get-only property.
a.string = 'xyz'

เอาท์พุท

abc ['a', 'b', 'c']
Traceback (most recent call last):
  File "./qtest.py", line 53, in <module>
    a.string = 'xyz'
AttributeError: can't set attribute

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

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

person PM 2Ring    schedule 20.05.2018
comment
สุดยอดครับ เรื่องนี้ดูเรียบร้อย ขอบคุณ! - person Neil; 20.05.2018
comment
@นีล ไม่ต้องกังวล ฉันได้เพิ่มข้อสังเกตอีกสองสามข้อในคำตอบของฉัน - person PM 2Ring; 20.05.2018