ฉันพบว่าทั้งสองงานต่อไปนี้:
class Foo():
def a(self):
print "hello"
class Foo(object):
def a(self):
print "hello"
คลาส Python ทั้งหมดควรขยายออบเจ็กต์หรือไม่ มีปัญหาที่อาจเกิดขึ้นกับการไม่ขยายวัตถุหรือไม่?
ฉันพบว่าทั้งสองงานต่อไปนี้:
class Foo():
def a(self):
print "hello"
class Foo(object):
def a(self):
print "hello"
คลาส Python ทั้งหมดควรขยายออบเจ็กต์หรือไม่ มีปัญหาที่อาจเกิดขึ้นกับการไม่ขยายวัตถุหรือไม่?
คำตอบ:
ใน Python 2 การไม่สืบทอดจากobject
จะสร้างคลาสแบบเก่าซึ่งทำให้เกิดtype
ผลลัพธ์ที่แตกต่างกัน:
>>> class Foo: pass
...
>>> type(Foo())
<type 'instance'>
เมื่อเทียบกับ
>>> class Bar(object): pass
...
>>> type(Bar())
<class '__main__.Bar'>
นอกจากนี้กฎสำหรับการสืบทอดหลายรายการยังแตกต่างกันในลักษณะที่ฉันจะไม่พยายามสรุปที่นี่ เอกสารที่ดีทั้งหมดที่ฉันเคยเห็นเกี่ยวกับ MI อธิบายถึงคลาสรูปแบบใหม่
ในที่สุดคลาสแบบเก่าก็หายไปใน Python 3 และการสืบทอดจากobject
กลายเป็นความหมายโดยปริยาย ดังนั้นจึงชอบคลาสสไตล์ใหม่ ๆ อยู่เสมอเว้นแต่คุณจะต้องการความเข้ากันได้กับซอฟต์แวร์รุ่นเก่า
ใน Python 3 คลาสจะขยายออกไปobject
โดยปริยายไม่ว่าคุณจะพูดเองหรือไม่ก็ตาม
ในหลาม 2 มีสไตล์เก่าและใหม่สไตล์ชั้นเรียน object
เพื่อส่งสัญญาณระดับเป็นแบบใหม่ที่คุณจะต้องสืบทอดอย่างชัดเจนจาก หากไม่เป็นเช่นนั้นจะใช้การใช้งานแบบเก่า
โดยทั่วไปคุณต้องการคลาสรูปแบบใหม่ สืบทอดobject
อย่างชัดเจน โปรดทราบว่าสิ่งนี้ใช้กับโค้ด Python 3 ที่มีจุดมุ่งหมายเพื่อให้เข้ากันได้กับ Python 2
ใน python 3 คุณสามารถสร้างคลาสได้สามวิธีและภายในจะเท่ากันทั้งหมด (ดูตัวอย่าง) มันไม่สำคัญว่าคุณจะสร้างชั้นเรียนทั้งหมดในหลาม 3 สืบทอดจากชั้นเรียนพิเศษที่เรียกว่า วัตถุ คลาสอ็อบเจ็กต์ เป็นคลาสพื้นฐานใน python และมีฟังก์ชันการทำงานมากมายเช่น double-underscore method, descriptors, super () method, property () method เป็นต้น
ตัวอย่าง 1.
class MyClass:
pass
ตัวอย่าง 2.
class MyClass():
pass
ตัวอย่างที่ 3.
class MyClass(object):
pass
object
object
หากเราต้องพิจารณาว่าตัวระบุในตัวของ CPython สามารถแทนที่ได้เราแทบจะไม่สามารถยืนยันเกี่ยวกับโมเดลข้อมูลได้ สามารถโต้แย้งอย่างจริงจังstr
ได้หรือไม่ที่ไม่ยอมรับสตริงเป็นอาร์กิวเมนต์เนื่องจากสามารถกำหนดได้builtins.str = None
?
ใช่คลาส Python ทั้งหมดควรขยาย (หรือมากกว่าคลาสย่อยนี่คือ Python ที่นี่) แม้ว่าโดยปกติจะไม่มีปัญหาร้ายแรงเกิดขึ้น แต่ในบางกรณี (เช่นเดียวกับการสืบทอดต้นไม้หลายต้น) สิ่งนี้จะมีความสำคัญ นอกจากนี้ยังช่วยให้สามารถใช้งานร่วมกับ Python 3 ได้ดีขึ้น
ตามคำตอบอื่น ๆ การสืบทอด Python 3 จากวัตถุนั้นเป็นนัย แต่พวกเขาไม่ได้ระบุว่าคุณควรทำอะไรและอะไรคือแบบแผน
ตัวอย่างเอกสาร Python 3 ทั้งหมดใช้สไตล์ต่อไปนี้ซึ่งเป็นแบบแผนดังนั้นฉันขอแนะนำให้คุณทำตามนี้สำหรับโค้ดในอนาคตใน Python 3
class Foo:
pass
ที่มา: https://docs.python.org/3/tutorial/classes.html#class-objects
ตัวอย่างคำพูด:
คลาสอ็อบเจ็กต์สนับสนุนการดำเนินการสองประเภท: การอ้างอิงแอตทริบิวต์และการสร้างอินสแตนซ์
การอ้างอิงแอตทริบิวต์ใช้ไวยากรณ์มาตรฐานที่ใช้สำหรับการอ้างอิงแอตทริบิวต์ทั้งหมดใน Python: obj.name ชื่อแอ็ตทริบิวต์ที่ถูกต้องคือชื่อทั้งหมดที่อยู่ในเนมสเปซของคลาสเมื่อสร้างคลาสอ็อบเจ็กต์ ดังนั้นหากคำจำกัดความของคลาสมีลักษณะดังนี้:
class MyClass: """A simple example class""" i = 12345 def f(self): return 'hello world'
คำพูดอื่น:
โดยทั่วไปตัวแปรอินสแตนซ์มีไว้สำหรับข้อมูลที่ไม่ซ้ำกันของแต่ละอินสแตนซ์และตัวแปรคลาสใช้สำหรับแอตทริบิวต์และวิธีการที่ใช้ร่วมกันโดยอินสแตนซ์ทั้งหมดของคลาส:
class Dog: kind = 'canine' # class variable shared by all instances def __init__(self, name): self.name = name # instance variable unique to each instance
ใน python3 ไม่มีความแตกต่าง แต่ใน python2 การไม่ขยายobject
จะให้คลาสแบบเก่าแก่คุณ คุณต้องการใช้คลาสสไตล์ใหม่กับคลาสแบบเก่า
class Foo():
และclass Foo:
หรือไม่? ตามที่ฉันสังเกตทั้งสองทำงานใน Python 3