ডেটাচলসগুলি যেভাবে বৈশিষ্ট্যগুলিকে একত্রিত করে তা আপনাকে বেস শ্রেণিতে ডিফল্টের সাথে অ্যাট্রিবিউট ব্যবহার করতে সক্ষম হতে এবং তারপরে একটি সাবক্লাসে ডিফল্ট (অবস্থানগত বৈশিষ্ট্য) ছাড়াই বৈশিষ্ট্যগুলি ব্যবহার করতে বাধা দেয়।
এটি কারণ এমআরওয়ের নীচ থেকে শুরু করে এবং প্রথম দেখা ক্রমে বিশদগুলির একটি আদেশযুক্ত তালিকা তৈরি করে বৈশিষ্ট্যগুলি একত্রিত করা হয়; ওভাররাইডগুলি তাদের মূল স্থানে রাখা হয়। সুতরাং যেখানে একটি ডিফল্ট আছে Parent
দিয়ে শুরু হয় , এবং তারপরে তালিকার শেষে যুক্ত হয় ( ইতিমধ্যে তালিকার সাথে)। এর অর্থ আপনার শেষ হয়েছে এবং এতে কোনও ডিফল্ট নেই কারণ এটির জন্য একটি অবৈধ যুক্তি তালিকার ফলাফল['name', 'age', 'ugly']
ugly
Child
['school']
ugly
['name', 'age', 'ugly', 'school']
school
__init__
।
এই নথিভুক্ত করা PEP-557 Dataclasses অধীন উত্তরাধিকার :
যখন ডেটা ক্লাসটি তৈরি করা হচ্ছে @dataclass
ডেকোরেটর , তখন এটি শ্রেণীর সমস্ত বেস ক্লাসগুলি বিপরীত এমআরওতে দেখায় (এটি শুরু করা হয় object
) এবং এটি যে ডেটা ক্লাস খুঁজে পায় তার জন্য সেই বেস বর্গ থেকে ক্ষেত্রগুলিকে একটি আদেশে যুক্ত করে ক্ষেত্রগুলির ম্যাপিং। সমস্ত বেস শ্রেণীর ক্ষেত্রগুলি যুক্ত হওয়ার পরে, এটি আদেশ ক্ষেত্রের ম্যাপিংয়ে নিজস্ব ক্ষেত্রগুলি যুক্ত করে। উত্পন্ন সমস্ত পদ্ধতি এই ক্ষেত্রগুলির সমন্বিত, গণনা করা আদেশযুক্ত ম্যাপিং ব্যবহার করবে। কারণ ক্ষেত্রগুলি সন্নিবেশ ক্রমে, উত্পন্ন ক্লাসগুলি বেস ক্লাসগুলিকে ওভাররাইড করে।
এবং নির্দিষ্টকরণের অধীনে :
TypeError
ডিফল্ট মানবিহীন একটি ক্ষেত্র যদি ডিফল্ট মান সহ কোনও ক্ষেত্র অনুসরণ করে তবে উত্থাপিত হবে। এটি সত্য হয় যখন এটি একটি একক শ্রেণিতে ঘটে থাকে বা শ্রেণীর উত্তরাধিকারের ফলস্বরূপ।
এই সমস্যাটি এড়াতে আপনার কাছে এখানে কয়েকটি বিকল্প রয়েছে।
প্রথম বিকল্পটি হ'ল এমআরও ক্রমের পরে অবস্থানে ডিফল্টগুলি সহ ক্ষেত্রগুলিকে বাধ্য করার জন্য পৃথক বেস ক্লাস ব্যবহার করা। যে কোনও মূল্যে, বেস ক্লাস যেমন ব্যবহার করা যেতে পারে এমন ক্লাসগুলিতে সরাসরি ক্ষেত্রগুলি স্থাপন করা এড়িয়ে চলুনParent
।
নিম্নলিখিত শ্রেণীর শ্রেণিবিন্যাস কাজ করে:
@dataclass
class _ParentBase:
name: str
age: int
@dataclass
class _ParentDefaultsBase:
ugly: bool = False
@dataclass
class _ChildBase(_ParentBase):
school: str
@dataclass
class _ChildDefaultsBase(_ParentDefaultsBase):
ugly: bool = True
@dataclass
class Parent(_ParentDefaultsBase, _ParentBase):
def print_name(self):
print(self.name)
def print_age(self):
print(self.age)
def print_id(self):
print(f"The Name is {self.name} and {self.name} is {self.age} year old")
@dataclass
class Child(Parent, _ChildDefaultsBase, _ChildBase):
pass
মধ্যে ক্ষেত্রগুলি টেনে পৃথক অক্ষমতা এবং অক্ষমতা সঙ্গে ক্ষেত্র ছাড়া ক্ষেত্র, এবং একটি যত্নসহকারে নির্বাচিত উত্তরাধিকার অর্ডার দিয়ে বেস ক্লাস, আপনি একটি ম্রো তৈরী করতে পারে যে অক্ষমতা যাদের সামনে অক্ষমতা ছাড়া রাখে সব ক্ষেত্র। বিপরীত এমআরও (উপেক্ষা করা object
) এর জন্য Child
:
_ParentBase
_ChildBase
_ParentDefaultsBase
_ChildDefaultsBase
Parent
নোট করুন যে Parent
কোনও নতুন ক্ষেত্র সেট করে না, তাই এখানে ক্ষেত্রের তালিকা ক্রমে এটি 'শেষ' হয়ে যায় তা এখানে গুরুত্বপূর্ণ নয়। অক্ষমতা ছাড়া ক্ষেত্রের সাথে ক্লাস ( _ParentBase
এবং _ChildBase
) অক্ষমতা সঙ্গে ক্ষেত্রের সাথে ক্লাস বসে ( _ParentDefaultsBase
এবং_ChildDefaultsBase
)।
ফলাফলটি হয়েছে Parent
এবং Child
বুদ্ধিমান ক্ষেত্রের সাথে ক্লাসগুলি পুরানো, যদিও Child
এখনও এটির একটি সাবক্লাস রয়েছে Parent
:
>>> from inspect import signature
>>> signature(Parent)
<Signature (name: str, age: int, ugly: bool = False) -> None>
>>> signature(Child)
<Signature (name: str, age: int, school: str, ugly: bool = True) -> None>
>>> issubclass(Child, Parent)
True
এবং তাই আপনি উভয় শ্রেণীর উদাহরণ তৈরি করতে পারেন:
>>> jack = Parent('jack snr', 32, ugly=True)
>>> jack_son = Child('jack jnr', 12, school='havard', ugly=True)
>>> jack
Parent(name='jack snr', age=32, ugly=True)
>>> jack_son
Child(name='jack jnr', age=12, school='havard', ugly=True)
অন্য বিকল্পটি হ'ল কেবলমাত্র খেলাপি খেলাগুলি ব্যবহার করা; আপনি এখনও কোনও school
মান বাড়িয়ে না দিয়ে ত্রুটি তৈরি করতে পারেন __post_init__
:
_no_default = object()
@dataclass
class Child(Parent):
school: str = _no_default
ugly: bool = True
def __post_init__(self):
if self.school is _no_default:
raise TypeError("__init__ missing 1 required argument: 'school'")
কিন্তু এই করে ক্ষেত্র অর্ডার পরিবর্তন করা; school
পরে শেষ ugly
:
<Signature (name: str, age: int, ugly: bool = True, school: str = <object object at 0x1101d1210>) -> None>
এবং একটি প্রকার ইঙ্গিত চেকার সম্পর্কে অভিযোগ করবে_no_default
স্ট্রিং না হওয়ার ।
আপনি attrs
প্রজেক্টটিও ব্যবহার করতে পারেন যা অনুপ্রেরণা করেছিল এমন প্রকল্প dataclasses
। এটি একটি পৃথক উত্তরাধিকার মার্জ করার কৌশল ব্যবহার করে; এটা ক্ষেত্র তালিকার শেষে একটি উপশ্রেণী ওভাররাইড করা ক্ষেত্র pulls, তাই ['name', 'age', 'ugly']
মধ্যে Parent
বর্গ হয়ে ['name', 'age', 'school', 'ugly']
এ Child
বর্গ; ডিফল্ট দিয়ে ফিল্ডটি ওভাররাইড করে attrs
একটি এমআরও নাচ না করে ওভাররাইডকে মঞ্জুরি দেয়।
attrs
প্রকার ইঙ্গিত ছাড়াই ক্ষেত্রগুলি সংজ্ঞায়িত করা সমর্থন করে, তবে সেটিংসের দ্বারা সমর্থিত প্রকার হিন্টিং মোডে আটকে দিন auto_attribs=True
:
import attr
@attr.s(auto_attribs=True)
class Parent:
name: str
age: int
ugly: bool = False
def print_name(self):
print(self.name)
def print_age(self):
print(self.age)
def print_id(self):
print(f"The Name is {self.name} and {self.name} is {self.age} year old")
@attr.s(auto_attribs=True)
class Child(Parent):
school: str
ugly: bool = True
ugly: bool = True
= rekt :)