PythonPython · Chapterبەش 11 · Lectureوانە 11.1
Classes and Objectsکلاسەکان و ئۆبجێکتەکان
Why programs are built from objects, the four big ideas of object-oriented programming at a glance, a class as the plan and objects as its instances, class, __init__ and self, attributes on each object, type() and isinstance(), variables as references to objects, a first method, printing an object, and the mistakes every beginner makes, such as forgetting self.
بۆچی لە دروست دەکرێن، چوار بیرۆکە گەورەکەی بە کورتی، وەک نەخشە و وەک ، class، __init__ و self، هەر ، type() و isinstance()، وەک بۆ ، یەکەم ، چاپکردنی و ئەو هەڵانەی هەموو تازەکارێک دەیانکات، وەک لەبیرچوونی self.
What you will learnچی فێر دەبیت
- Explain how object-oriented programming differs from procedural programming, and name its four big ideas.
- Write a class with
__init__, make several objects (instances) from it, and read and change their attributes. - Explain what
selfis and whyaram.describe()meansStudent.describe(aram). - Check an object's class with
type()andisinstance(). - Explain that a variable holds a reference to an object, and predict what happens when two names share one object.
- Write a first method and a
__str__method, and fix the common errors such as a missingself.
- ڕوون بکەیتەوە چ جیاوازییەکی لەگەڵ هەیە و ناوی چوار بیرۆکە گەورەکەی بهێنیت.
- بە
__init__بنووسیت، چەند () لێی دروست بکەیت و بخوێنیتەوە و بیانگۆڕیت. - ڕوون بکەیتەوە
selfچییە و بۆچیaram.describe()واتەStudent.describe(aram). - بە
type()وisinstance()بپشکنیت. - ڕوون بکەیتەوە کە بۆ هەڵدەگرێت و پێشبینی بکەیت چی ڕوو دەدات کاتێک دوو ناو یەک بەش دەکەن.
- یەکەم و
__str__بنووسیت و هەڵە باوەکان چاک بکەیت، وەک نەبوونیself.
Why objects?بۆچی ئۆبجێکتەکان؟
Until now your programs kept their data in variables, lists and dictionaries, and their actions in functions. A marks program might keep each student in a dictionary and have separate functions such as average(student) and describe(student). This style is called procedural programming: the program is a series of steps grouped into functions.
تا ئێستا لە ، و هەڵدەگرت و کارەکانیان لە . نمرە لەوانەیە هەر قوتابییەک لە هەڵبگرێت و چەند جیای وەک average(student) و describe(student)ـی هەبێت. بەم شێوازە دەگوترێت : زنجیرەیەک هەنگاوە کە لە کۆ کراونەتەوە.
This works well for small programs. As a program grows, the data and the functions drift apart: any function can change any dictionary, a typo in a key such as "mraks" is found only when that line runs, and nothing says which functions belong to which data. Object-oriented programming (OOP) puts each piece of data together with the actions that use it, in one unit called an object. Python itself is object-oriented: every value you have used, from 5 to "Aram", is already an object.
ئەمە بۆ بچووک باش کار دەکات. کاتێک گەورە دەبێت، و لە یەک دوور دەکەونەوە: هەر دەتوانێت هەر بگۆڕێت، هەڵەیەکی نووسین لە وەک "mraks" تەنیا کاتێک دەردەکەوێت کە ئەو دێڕە جێبەجێ دەبێت و هیچ شتێک نالێت کام هی کام . (OOP) هەر پارچە لەگەڵ ئەو کارانەی بەکاری دەهێنن لە یەک یەکەدا کۆ دەکاتەوە کە پێی دەگوترێت . خۆی : هەموو ئەو تا ئێستا بەکارت هێناون، لە 5ـەوە تا "Aram"، پێشتر .
Why objects?بۆچی ئۆبجێکتەکان؟
One program, two stylesیەک بەرنامە، دوو شێواز
Here is the same small marks program twice. First the procedural version, which you can already write:
ئەمە هەمان بچووکی نمرەیە بە دوو شێوە. یەکەم، شێوە ڕێکارییەکە کە پێشتر دەتوانیت بینووسیت:
# Procedural style: the data in dictionaries, the functions apart
aram = {"name": "Aram", "grade": 10, "marks": [80, 92, 75]}
shilan = {"name": "Shilan", "grade": 11, "marks": [95, 88, 91]}
def average(student):
return sum(student["marks"]) / len(student["marks"])
def describe(student):
return f"{student['name']} (grade {student['grade']})"
for s in [aram, shilan]:
print(describe(s), "average:", round(average(s), 1))Aram (grade 10) average: 82.3 Shilan (grade 11) average: 91.3
Now the object-oriented version. Do not worry about the new words yet: class, __init__ and self are explained one by one in this lesson. Look at the shape: the data and the two actions now live together inside Student, and you ask each student object for its own average:
ئێستا شێوە . هێشتا خەمی وشە نوێیەکان مەخۆ: class، __init__ و self یەک بە یەک لەم وانەیەدا ڕوون دەکرێنەوە. سەیری شێوەکەی بکە: و هەردوو کارەکە ئێستا پێکەوە لە ناو Studentـدان و لە هەر قوتابی تێکڕای خۆی دەپرسیت:
# Object-oriented style: each student keeps its data and its actions
class Student:
def __init__(self, name, grade, marks):
self.name = name
self.grade = grade
self.marks = marks
def average(self):
return sum(self.marks) / len(self.marks)
def describe(self):
return f"{self.name} (grade {self.grade})"
aram = Student("Aram", 10, [80, 92, 75])
shilan = Student("Shilan", 11, [95, 88, 91])
for s in [aram, shilan]:
print(s.describe(), "average:", round(s.average(), 1))Aram (grade 10) average: 82.3 Shilan (grade 11) average: 91.3
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 2-12
The class: the data (
name,grade,marks) and the actions (average,describe) in one place.: (
name،grade،marks) و کارەکان (average،describe) لە یەک شوێندا.- Lineدێڕی 18
s.average()asks the objectsfor its own average.s.average()تێکڕای خودیsدەپرسێت.
Both print the same lines. The difference shows in bigger programs: a Student object cannot be made without a name, a grade and marks, and all the code that works on students is in one place. Where Python stands among other languages is in Programming languages.
هەردووکیان هەمان دێڕەکان چاپ دەکەن. جیاوازییەکە لە گەورەتردا دەردەکەوێت: Student بەبێ ناو، پۆل و نمرە دروست ناکرێت و هەموو ئەو کۆدەی لەسەر قوتابییەکان کار دەکات لە یەک شوێندایە. لە نێوان زمانەکانی تردا لە کوێیە، لە زمانەکانی بەرنامەسازیدایە.
Four big ideas at a glanceچوار بیرۆکەی گەورە بە کورتی
Object-oriented programming rests on four ideas. You meet each of them properly later; here is the map:
لەسەر چوار بیرۆکە وەستاوە. هەریەکەیان دواتر بە تەواوی دەناسیت؛ ئەمە نەخشەکەیە:
- Encapsulation: an object keeps its data and the methods that use it together, and other code changes the data only in safe ways, through the methods — like a shop's cash box: customers pay through the shopkeeper. Encapsulation and properties.
- Abstraction: you use an object through a few simple actions without knowing how it works inside, as you use a phone's buttons without knowing its circuits.
marks.sort()sorts without showing you how. - Inheritance: a new class is built from an existing one and gets its data and methods, then adds or changes some: a
Studentand aTeachercan both be built from aPerson. Inheritance and polymorphism. - Polymorphism: one call works on different kinds of objects, each in its own way:
len()counts the letters of a string and the items of a list.
- : خۆی و ئەو بەکاری دەهێنن پێکەوە هەڵدەگرێت و کۆدی تر تەنیا بە شێوەی سەلامەت، لە ڕێگەی ، دەگۆڕێت — وەک سندووقی پارەی دووکانێک: کڕیار لە ڕێگەی دووکاندارەکەوە پارە دەدات. کەپسوولکردن و تایبەتمەندییەکان.
- : لە ڕێگەی چەند کارێکی سادەوە بەکار دەهێنیت بەبێ ئەوەی بزانیت لە ناوەوە چۆن کار دەکات، وەک چۆن دوگمەکانی مۆبایل بەکار دەهێنیت بەبێ ئەوەی ئەلیکترۆنییەکەی بزانیت.
marks.sort()ڕیزی دەکات بەبێ ئەوەی پیشانت بدات چۆن. - : نوێ لە هەبوو دروست دەکرێت و و ئەو وەردەگرێت، پاشان هەندێکیان زیاد دەکات یان دەیانگۆڕێت:
StudentوTeacherهەردووکیان دەتوانن لەPersonدروست بکرێن. بۆماوە و فرەشێوەیی. - : یەک بانگکردن لەسەر چەند جۆرێکی کار دەکات و هەریەکەیان بە شێوەی خۆی:
len()پیتەکانی و دانەکانی دەژمێرێت.
A class is the plan; objects are made from itکلاس نەخشەکەیە؛ ئۆبجێکتەکان لێیەوە دروست دەکرێن
A class describes a kind of thing: which data every thing of that kind has, and what it can do. A class is not a thing itself. An object is one real thing made from the class, with its own values. One Student class can make the objects aram, shilan and karwan; each has its own name and grade.
جۆرێک شت وەسف دەکات: هەموو شتێکی ئەو جۆرە چ هەیە و دەتوانێت چی بکات. خۆی شت نییە. یەک شتی ڕاستەقینەیە کە لە دروست کراوە و خۆی هەیە. یەک Student دەتوانێت aram، shilan و karwan دروست بکات؛ هەریەکەیان ناو و پۆلی خۆی هەیە.
A shop in the bazaar prints one order form with empty lines: Name, Item, Amount. That printed form is the class. Every customer gets a copy and fills it in: Aram writes tea, 2 kg; Shilan writes rice, 5 kg. Each filled form is an object. The shop designs the form once but fills in hundreds, and a change on one customer's form does not change the others.
دووکانێک لە بازاڕدا یەک فۆڕمی داواکاری بە دێڕی بەتاڵەوە چاپ دەکات: ناو، کاڵا، بڕ. ئەو فۆڕمە چاپکراوە . هەر کڕیارێک کۆپییەک وەردەگرێت و پڕی دەکاتەوە: ئارام دەنووسێت چا، 2 کگم؛ شیلان دەنووسێت برنج، 5 کگم. هەر فۆڕمێکی پڕکراو . دووکانەکە یەک جار فۆڕمەکە دیزاین دەکات، بەڵام سەدان دانە پڕ دەکاتەوە و گۆڕینی فۆڕمی کڕیارێک فۆڕمەکانی تر ناگۆڕێت.
Where the analogy stops workingسنووری ئەم نموونەیە
A paper form only holds values. A class also has actions (methods) and can check the values it is given, which paper cannot do.
فۆڕمی کاغەز تەنیا هەڵدەگرێت. کاریشی () هەیە و دەتوانێت ئەو پێی دەدرێن بپشکنێت، کە کاغەز ناتوانێت.
A class is the plan; objects are made from itکلاس نەخشەکەیە؛ ئۆبجێکتەکان لێیەوە دروست دەکرێن
Instances: you have used them all alongنموونەکان: هەمیشە بەکارت هێناون
An object made from a class is called an instance of that class, and making it is called instantiation. Every value in Python is an instance of some class. type() shows which one, and the methods you already call, such as upper() and append(), belong to those classes:
کە لە دروست دەکرێت پێی دەگوترێت ئەو و دروستکردنەکەی پێی دەگوترێت instantiation. هەموو لە . type() پیشان دەدات کامیان و ئەو پێشتر بانگت کردوون، وەک upper() و append()، هی ئەو :
print(type(2026))
print(type("Hana"))
print(type([80, 92]))
name = "shilan"
print(name.upper()) # upper() is a method of every str object
marks = [80, 92]
marks.append(75) # append() is a method of every list object
print(marks)<class 'int'> <class 'str'> <class 'list'> SHILAN [80, 92, 75]
So "shilan" is an instance of the class str, and marks is an instance of list. In this lesson you write your own classes, like Student, and make instances of them in the same way.
کەواتە "shilan" strـە و marks listـە. لەم وانەیەدا خۆت دەنووسیت (وەک Student) و بە هەمان شێوە لێ دروست دەکەیت.
Your first classیەکەم کلاست
A class starts with the keyword class, a name and a colon; its body is indented. Python's style guide (PEP 8) writes class names in CapWords: Student, ExamResult. The smallest class has only pass in its body. To make an object, call the class like a function, with brackets:
بە class، ناوێک و دوو خاڵ دەست پێ دەکات؛ لاشەکەی بە دەنووسرێت. ڕێبەری شێوازی (PEP 8) ناوی بە CapWords دەنووسێت: Student، ExamResult. بچووکترین تەنیا passـی لە لاشەکەیدایە. بۆ دروستکردنی ، بانگ بکە وەک ، بە کەوانەوە:
class Student:
pass # an empty class: no data, no actions yet
aram = Student() # call the class to make an object
shilan = Student() # a second, separate object
print(aram)
print(type(aram))
print(aram is shilan)<__main__.Student object at 0x109b9e900> <class '__main__.Student'> False
The number after at is the object's place in memory; it changes every time you run the program.
ئەو ژمارەیەی دوای at شوێنی لە ؛ هەر جارێک کار پێ بکەیت دەگۆڕێت.
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 4-5
Each call
Student()makes a new, separate object.هەر بانگکردنێکی
Student()نوێ و جیا دروست دەکات.
print(aram) shows the class (Student, written in the main program __main__) and a memory address. The two calls made two different objects, so aram is shilan is False. This class is still empty; next it gets data.
print(aram) (Student، کە لە سەرەکی __main__ـدا نووسراوە) و پیشان دەدات. دوو بانگکردنەکە دوو جیاوازیان دروست کرد، بۆیە aram is shilan Falseـە. ئەم هێشتا بەتاڵە؛ دواتر وەردەگرێت.
__init__: filling in the form__init__: پڕکردنەوەی فۆڕمەکە
Most objects need values from the start: a student needs a name and a grade. A class receives them in a special method called __init__ (two underscores on each side). Python runs it by itself every time you make an object and passes in the values you gave. It is usually called the class's constructor; strictly it is an initialiser: the empty object already exists when __init__ runs, and __init__ fills it in:
زۆربەی لە سەرەتاوە پێویستیان بە هەیە: قوتابی پێویستی بە ناو و پۆل هەیە. ئەمانە لە تایبەتدا بە ناوی __init__ وەردەگرێت (دوو هێڵی ژێرەوە لە هەر لایەک). خۆی هەموو جارێک کە دروست دەکەیت جێبەجێی دەکات و ئەو داوتن دەینێرێتە ناوی. زۆربەی جار پێی دەگوترێت ؛ بە وردی دەستپێکەرە: بەتاڵەکە پێش کارکردنی __init__ هەیە و __init__ پڕی دەکاتەوە:
class Student:
def __init__(self, name, grade):
self.name = name # store the value in this object
self.grade = grade
aram = Student("Aram", 10)
shilan = Student("Shilan", 11)
print(aram.name, aram.grade)
print(shilan.name, shilan.grade)Aram 10 Shilan 11
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 2
__init__has a first parameterself, then the values you pass:nameandgrade.__init__یەکەمselfـە، پاشان ئەو دەیاننێریت:nameوgrade.- Lineدێڕی 3-4
self.name = namestores the value inside this object, as its attributename.self.name = nameلە ناو ئەم وەکnameهەڵدەگرێت.
Student("Aram", 10) works in steps: Python makes a new, empty Student object, calls __init__ with self = that new object, name = "Aram" and grade = 10, and finally gives the finished object back, which aram = stores. The animation shows the steps.
Student("Aram", 10) هەنگاو بە هەنگاو کار دەکات: نوێ و بەتاڵی Student دروست دەکات، __init__ بانگ دەکات بە self = ئەو نوێیە، name = "Aram" و grade = 10، لە کۆتاییدا تەواوکراوەکە دەگەڕێنێتەوە و aram = هەڵیدەگرێت. ئەنیمەیشنەکە هەنگاوەکان پیشان دەدات.


Student("Aram", 10) does, step by step.Student("Aram", 10) هەنگاو بە هەنگاو چی دەکات.CêIT__init__: filling in the form__init__: پڕکردنەوەی فۆڕمەکە
What self really isself لە ڕاستیدا چییە
self is simply the first parameter of every method in a class. When you call a method through an object, Python puts that object into self for you. So aram.describe() means exactly Student.describe(aram): inside the method, self.name is Aram's name. Called through shilan, the same code reads Shilan's name.
self تەنیا یەکەم هەموو ناو . کاتێک لە ڕێگەی بانگ دەکەیت، خۆی ئەو دەخاتە ناو self. کەواتە aram.describe() ڕێک واتە Student.describe(aram): لە ناو self.name ناوی ئارامە. ئەگەر لە ڕێگەی shilanـەوە بانگ بکرێت، هەمان کۆد ناوی شیلان دەخوێنێتەوە.
self ئەو ئۆبجێکتەیە کە پێش خاڵەکەیەwhat_is_self.pyPYTHONType in a terminalلە تێرمیناڵدا بینووسەclass Student:
def __init__(self, name, grade):
self.name = name
self.grade = grade
def describe(self):
return f"{self.name} is in grade {self.grade}"
def my_id(self):
return id(self)
aram = Student("Aram", 10)
print(aram.describe())
print(Student.describe(aram)) # the same call, written out in full
print(aram.my_id() == id(aram)) # self is the object aram itselfAram is in grade 10 Aram is in grade 10 True
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 14
Written out in full: the class, the method, and the object as the first argument.
بە تەواوی نووسراو: ، و وەک یەکەم .
- Lineدێڕی 15
id()gives an object's identity number:selfandaramare one object.id()ژمارەی ناسنامەی دەدات:selfوaramیەک .
The name self is a convention, not a keyword: Python would accept another name, but every Python programmer writes self (PEP 8 asks for it), so always use it. Java does the same job with the keyword this: this in Java.
ناوی self ڕێککەوتنێکە، نەک : ناوێکی تریش قبووڵ دەکات، بەڵام هەموو self دەنووسێت (PEP 8 داوای دەکات)، بۆیە هەمیشە ئەوە بەکار بهێنە. هەمان کار بە this دەکات: this لە Java.
aram.describe() is Student.describe(aram): the object before the dot becomes self.aram.describe() هەمان Student.describe(aram)ـە: ئەو پێش خاڵەکەیە دەبێتە self.CêITAttributes: each object's own dataخەسڵەتەکان: دراوەی تایبەتی هەر ئۆبجێکتێک
A value stored in an object, such as aram.name, is an attribute. Values made with self. in __init__ are instance attributes: every object has its own. Read or change one with the object, a dot and the attribute's name. vars() shows all the attributes of an object as a dictionary:
کە لە هەڵگیراوە، وەک aram.name، . ئەو لە __init__ـدا بە self. دروست دەکرێن ن: هەر هی خۆی هەیە. بە ، خاڵێک و ناوی دەیخوێنیتەوە یان دەیگۆڕیت. vars() هەموو وەک پیشان دەدات:
class Student:
def __init__(self, name, grade):
self.name = name
self.grade = grade
aram = Student("Aram", 10)
shilan = Student("Shilan", 12)
aram.grade = 11 # change one object's attribute
print(aram.grade, shilan.grade)
print(vars(aram)) # every attribute of aram
print(vars(shilan))11 12
{'name': 'Aram', 'grade': 11}
{'name': 'Shilan', 'grade': 12}Changing aram.grade did not touch shilan.grade: two objects, two sets of attributes. Python even lets you add an attribute later (aram.phone = ...), but good classes make every attribute in __init__, so all objects of the class have the same shape.
گۆڕینی aram.grade دەستی لە shilan.grade نەدا: دوو ، دوو کۆمەڵ . تەنانەت ڕێگە دەدات دواتر زیاد بکەیت (aram.phone = ...)، بەڵام باش هەموو لە __init__ـدا دروست دەکات، بۆیە هەموو ئەو هەمان شێوەیان هەیە.
Attributes: each object's own dataخەسڵەتەکان: دراوەی تایبەتی هەر ئۆبجێکتێک
A typo and a missing attributeهەڵەیەکی نووسین و خەسڵەتێکی ون
Assigning to an attribute creates it if it does not exist. So a typo does not stop the program: it quietly makes a second attribute. Reading an attribute that was never made stops the program with an AttributeError:
دانانی بۆ ئەگەر بوونی نەبێت دروستی دەکات. بۆیە هەڵەیەکی نووسین ناوەستێنێت: بە بێدەنگی دووەم دروست دەکات. خوێندنەوەی کە هەرگیز دروست نەکراوە بە AttributeError دەوەستێنێت:
class Student:
def __init__(self, name, grade):
self.name = name
self.grade = grade
aram = Student("Aram", 10)
aram.grdae = 11 # typo: Python makes a NEW attribute
print(aram.grade)
print(vars(aram))
print(aram.mark) # this attribute was never made10
{'name': 'Aram', 'grade': 10, 'grdae': 11}
Traceback (most recent call last):
File "attribute_typo.py", line 10, in <module>
print(aram.mark) # this attribute was never made
^^^^^^^^^
AttributeError: 'Student' object has no attribute 'mark'aram.grdae = 11 made a new attribute grdae, and aram.grade is still 10: a silent bug, but vars() shows it. aram.mark was never assigned, so Python raises AttributeError: 'Student' object has no attribute 'mark'. Read it as: this object has no such attribute; check the spelling, or set it in __init__.
aram.grdae = 11 نوێی grdae دروست کرد و aram.grade هێشتا 10ـە: بێدەنگ، بەڵام vars() پیشانی دەدات. aram.mark هەرگیز بۆ دانەنراوە، بۆیە AttributeError: 'Student' object has no attribute 'mark' دروست دەکات. بەم شێوەیە بیخوێنەوە: ئەم ئەو نییە؛ ڕێنووسەکە بپشکنە، یان لە __init__ـدا دایبنێ.
Which class? type() and isinstance()کام کلاس؟ type() و isinstance()
type(x) gives the class of an object. isinstance(x, C) asks a yes-or-no question: is x an instance of the class C? It is the better check in an if, because it also says yes for classes built from C. True is an instance of int, since the class bool is built from int (inheritance):
type(x) دەدات. isinstance(x, C) پرسیارێکی بەڵێ یان نەخێر دەکات: ئایا x Cـە؟ لە ناو ifـدا پشکنینی باشترە، چونکە بۆ ئەو لە C دروست کراون بەڵێش دەڵێت. True intـە، چونکە bool لە int دروست کراوە (بۆماوە):
class Student:
def __init__(self, name):
self.name = name
class Teacher:
def __init__(self, name):
self.name = name
people = [Student("Aram"), Teacher("Hana"), Student("Karwan")]
for p in people:
print(p.name, type(p).__name__, isinstance(p, Student))
print(isinstance(2026, int), isinstance(True, int), type(True) is int)Aram Student True Hana Teacher False Karwan Student True True True False
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 11
type(p).__name__is the class's name as text.type(p).__name__ناوی وەک دەق.
Use isinstance() when a function must check what it was given, for example if not isinstance(mark, int): before it uses a mark.
کاتێک دەبێت بپشکنێت چی پێ دراوە isinstance() بەکار بهێنە، بۆ نموونە if not isinstance(mark, int): پێش ئەوەی نمرەیەک بەکار بهێنێت.
isinstance() answers: is this object an instance of that class?isinstance() وەڵام دەداتەوە: ئایا ئەم ئەو ؟CêITA variable holds a reference to an objectگۆڕاوێک ئاماژەیەک بۆ ئۆبجێکتێک هەڵدەگرێت
A variable does not contain the object itself; it holds a reference to it, like a name tag tied to a box, exactly as with lists. monitor = aram ties a second tag to the same object, so a change through one name is seen through the other. A new object with the same values is still a different object:
خودی لە خۆیدا هەڵناگرێت؛ بۆی هەڵدەگرێت، وەک تاگێکی ناو کە بە سندووقێکەوە بەسترابێت، ڕێک وەک لیستەکان. monitor = aram تاگێکی دووەم بە هەمان دەبەستێت، بۆیە گۆڕانێک لە ڕێگەی ناوێکەوە لە ڕێگەی ئەوی تریشەوە دەبینرێت. نوێ بە هەمان هێشتا ترە:
import copy
class Student:
def __init__(self, name, grade):
self.name = name
self.grade = grade
aram = Student("Aram", 10)
monitor = aram # a second name, not a copy
monitor.grade = 11
print(aram.grade, monitor is aram)
twin = Student("Aram", 11) # a new object with the same values
print(twin is aram, twin == aram)
spare = copy.copy(aram) # a real copy: a new object
spare.grade = 12
print(aram.grade, spare.grade)11 True False False 11 12
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 9
monitoris a second name for Aram's object, not a new student.monitorناوێکی دووەمە بۆ ئارام، نەک قوتابییەکی نوێ.- Lineدێڕی 16
copy.copy()makes a new object with the same attributes.copy.copy()نوێ بە هەمان دروست دەکات.
is asks "the same object?". For your own classes, == asks the same question until you teach it to compare values with __eq__ (comparing objects); that is why twin == aram is False. For objects that hold lists, also read about shallow and deep copies.
is دەپرسێت «هەمان ؟». بۆ خۆت، == هەمان پرسیار دەکات تا ئەو کاتەی بە __eq__ فێری دەکەیت بەراورد بکات (بەراوردکردنی ئۆبجێکتەکان)؛ بۆیە twin == aram Falseـە. بۆ ئەو هەڵدەگرن، هەروەها کۆپیی ڕووکەش و کۆپیی قووڵ بخوێنەوە.
A variable holds a reference to an objectگۆڕاوێک ئاماژەیەک بۆ ئۆبجێکتێک هەڵدەگرێت
Passing an object to a functionناردنی ئۆبجێکتێک بۆ کردارێک
A parameter is one more name for the object the caller gave. So a function can change an object, and the caller sees the change after the call, exactly like a list passed to a function:
ناوێکی ترە بۆ ئەو داویەتی. بۆیە دەتوانێت بگۆڕێت و دوای بانگکردنەکە گۆڕانەکە دەبینێت، ڕێک وەک لیستێک کە دەنێردرێت بۆ کردارێک:
class Student:
def __init__(self, name, grade):
self.name = name
self.grade = grade
def promote(student):
student.grade += 1 # changes the object the caller gave
aram = Student("Aram", 10)
promote(aram)
promote(aram)
print(aram.name, aram.grade)Aram 12
Inside promote(), student and the caller's aram are two tags on one object, so student.grade += 1 changes Aram's grade; called twice, it goes from 10 to 12. Such a function works on students, and a little later you move it into the class as a method.
لە ناو promote()ـدا، student و aramـی دوو تاگن لەسەر یەک ، بۆیە student.grade += 1 پۆلی ئارام دەگۆڕێت؛ دوو جار بانگ کرا، لە 10ـەوە دەچێتە 12. ئەم جۆرە لەسەر قوتابییەکان کار دەکات و کەمێک دواتر دەیگوازیتەوە ناو وەک .
student and the caller's aram point to the same object. student و aramـی ئاماژە بۆ هەمان دەکەن.CêITA variable holds a reference to an objectگۆڕاوێک ئاماژەیەک بۆ ئۆبجێکتێک هەڵدەگرێت
A list of objectsلیستێک لە ئۆبجێکتەکان
A list can hold objects like any other value; each item is a reference to one object. A loop then visits every student and reads its attributes with the dot. This program prints a small table and finds the best mark:
دەتوانێت وەک هەر تر هەڵبگرێت؛ هەر دانەیەک بۆ یەک . پاشان سەردانی هەموو قوتابییەک دەکات و بە خاڵ دەخوێنێتەوە. ئەم خشتەیەکی بچووک چاپ دەکات و باشترین نمرە دەدۆزێتەوە:
class Student:
def __init__(self, name, mark):
self.name = name
self.mark = mark
students = [Student("Aram", 78), Student("Shilan", 93), Student("Karwan", 85)]
best = students[0]
for s in students:
print(f"{s.name:<8}{s.mark}")
if s.mark > best.mark:
best = s
print("Best:", best.name)Aram 78 Shilan 93 Karwan 85 Best: Shilan
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 10
{s.name:<8}pads the name to 8 characters: format specifiers.{s.name:<8}ناوەکە بە بۆشایی دەگەیەنێتە 8 : دیاریکەرەکانی شێواز.- Lineدێڕی 12
bestrefers to the best object so far; at the end it is Shilan's.bestئاماژە بۆ باشترین تا ئێستا دەکات؛ لە کۆتاییدا هی شیلانە.
best = s copies a reference, not a student: best simply points at the object with the top mark. With objects, the name and the mark of each student stay together, so they can never get out of step as two parallel lists can.
best = s کۆپی دەکات، نەک قوتابییەک: best تەنیا ئاماژە بۆ ئەو دەکات کە بەرزترین نمرەی هەیە. بە ، ناو و نمرەی هەر قوتابییەک پێکەوە دەمێننەوە، بۆیە هەرگیز لە یەک جیا نابنەوە، بە پێچەوانەی دوو تەریب.
A first method: what an object can doیەکەم میتۆد: ئۆبجێکتێک دەتوانێت چی بکات
A method is a function written inside a class. Its first parameter is self, so it can use the object's attributes. A method can return a value made from the attributes, or change them:
کە لە ناو نووسراوە. یەکەم selfـە، بۆیە دەتوانێت بەکار بهێنێت. دەتوانێت کە لە دروست کراوە بگەڕێنێتەوە، یان ئەوان بگۆڕێت:
class Student:
def __init__(self, name, grade):
self.name = name
self.grade = grade
def describe(self): # a method that returns text
return f"{self.name} is in grade {self.grade}"
def promote(self): # a method that changes the object
self.grade += 1
aram = Student("Aram", 10)
print(aram.describe())
aram.promote()
print(aram.describe())Aram is in grade 10 Aram is in grade 11
aram.promote() changes Aram only, because self is Aram. Compare it with promote(student) two screens back: the code is the same, but now it lives with the data it changes, and every Student object has it. Methods with parameters, methods that return answers and Python's special methods are in the next lesson, Attributes and methods.
aram.promote() تەنیا ئارام دەگۆڕێت، چونکە self ئارامە. بەراوردی بکە لەگەڵ promote(student) دوو شاشە پێشتر: کۆدەکە هەمانە، بەڵام ئێستا لەگەڵ ئەو دەژی کە دەیگۆڕێت و هەموو Student هەیەتی. بە ، ئەو وەڵام دەگەڕێننەوە و لە وانەی داهاتوودان: خەسڵەتەکان و میتۆدەکان.
Printing an objectچاپکردنی ئۆبجێکتێک
print() of your own object shows only its class and memory address, which tells a reader nothing:
print()ـی خۆت تەنیا و پیشان دەدات کە هیچ شتێک بە خوێنەر نالێت:
class Student:
def __init__(self, name, grade):
self.name = name
self.grade = grade
aram = Student("Aram", 10)
print(aram)<__main__.Student object at 0x10209e900>
The address changes from run to run.
ناونیشانەکە لە هەر جارێکی کارکردندا دەگۆڕێت.
Add a method named __str__ that returns the text you want. print() and str() call it for you:
بە ناوی __str__ زیاد بکە کە ئەو دەقەی دەتەوێت بگەڕێنێتەوە. print() و str() خۆیان بانگی دەکەن:
__str__printing_str.pyPYTHONType in a terminalلە تێرمیناڵدا بینووسەclass Student:
def __init__(self, name, grade):
self.name = name
self.grade = grade
def __str__(self): # the text print() should show
return f"{self.name} (grade {self.grade})"
aram = Student("Aram", 10)
print(aram)
print("Top student: " + str(aram))Aram (grade 10) Top student: Aram (grade 10)
__str__ is one of Python's special methods: names with two underscores on each side, like __init__, that Python calls by itself. The next lesson shows __str__ beside __repr__ and __eq__: __str__ and __repr__. Java does the same with toString(): printing objects in Java.
__str__ یەکێکە لە : ئەو ناوانەی دوو هێڵی ژێرەوەیان لە هەر لایەکەوە هەیە، وەک __init__، کە خۆی بانگیان دەکات. وانەی داهاتوو __str__ لە تەنیشت __repr__ و __eq__ پیشان دەدات: __str__ و __repr__. هەمان کار بە toString() دەکات: چاپکردنی ئۆبجێکتەکان لە Java.
print(aram) before and after the class gets a __str__ method.هەمان print(aram) پێش و دوای ئەوەی __str__ وەربگرێت.CêITCommon mistake: forgetting selfهەڵەی باو: لەبیرچوونی self
The most common error with a first class is a method without self. Python always passes the object as the first argument, so a method with no parameters has no place for it:
باوترین هەڵە لە یەکەم بێ self. هەمیشە وەک یەکەم دەنێرێت، بۆیە کە نییە شوێنی بۆی نییە:
selfmistake_no_self.pyPYTHONType in a terminalلە تێرمیناڵدا بینووسەclass Student:
def __init__(self, name):
self.name = name
def describe(): # self is missing
return "a student"
aram = Student("Aram")
print(aram.describe())Traceback (most recent call last):
File "mistake_no_self.py", line 9, in <module>
print(aram.describe())
~~~~~~~~~~~~~^^
TypeError: Student.describe() takes 0 positional arguments but 1 was givenRead the last line of the traceback: describe() takes 0 positional arguments but 1 was given. The one argument is aram, which Python sent. The fix is def describe(self):.
دوا دێڕی ڕێچکەی هەڵە بخوێنەوە: describe() takes 0 positional arguments but 1 was given. ئەو یەک aramـە، کە ناردی. چارەسەرەکە def describe(self):ـە.
self first. هەمیشە دەنێرێت: هەموو پێویستی بە self لە پێشەوە هەیە.CêITCommon mistake: forgetting selfهەڵەی باو: لەبیرچوونی self
More common mistakesهەڵە باوەکانی تر
Each mistake below was run with Python 3.13; the table shows the last line Python printed and the fix.
هەریەکە لەم هەڵانەی خوارەوە بە 3.13 تاقی کرایەوە؛ خشتەکە دوا دێڕێک کە چاپی کرد و چارەسەرەکە پیشان دەدات.
| Mistakeهەڵە | What Python says چی دەڵێت | Fixچارەسەر |
|---|---|---|
name = name in __init__name = name لە __init__ـدا | AttributeError: 'Student' object has no attribute 'name' | self.name = name: without self. it is only a local variable that disappears.self.name = name: بەبێ self. تەنیا کە ون دەبێت. |
Student("Aram") when __init__ needs a name and a gradeStudent("Aram") کاتێک __init__ ناو و پۆلی دەوێت | TypeError: Student.__init__() missing 1 required positional argument: 'grade' | Pass every value __init__ asks for (or give it a default).هەموو ئەو __init__ داوایان دەکات بنێرە (یان بۆ دابنێ). |
def _init_(self, name): with one underscoredef _init_(self, name): بە یەک هێڵی ژێرەوە | TypeError: Student() takes no arguments | Two underscores on each side: __init__.دوو هێڵی ژێرەوە لە هەر لایەک: __init__. |
return a value from __init__گەڕاندنەوەی لە __init__ | TypeError: __init__() should return None, not 'str' | __init__ only fills in the object; leave out return.__init__ تەنیا پڕ دەکاتەوە؛ return لاببە. |
print(aram.describe) without bracketsprint(aram.describe) بێ کەوانە | <bound method Student.describe of <__main__.Student object at 0x104232900>> | No error, but the method was not called: write aram.describe().هەڵە نییە، بەڵام بانگ نەکرا: aram.describe() بنووسە. |
Exercisesڕاهێنانەکان
Write a class Teacher with the attributes name and subject and a method introduce() that returns a sentence such as "I am Hana and I teach Maths.". Make two teachers and print both introductions.
Teacher بنووسە بە name و subject و introduce() کە ڕستەیەکی وەک "I am Hana and I teach Maths." بگەڕێنێتەوە. دوو مامۆستا دروست بکە و ناساندنی هەردووکیان چاپ بکە.
Hintئاماژە
Copy the shape of Student: __init__ stores the two values with self., and the method uses self.name and self.subject.
شێوەی Student کۆپی بکە: __init__ دوو بە self. هەڵدەگرێت و self.name و self.subject بەکار دەهێنێت.
Show answerوەڵامەکە پیشان بدە
class Teacher:
def __init__(self, name, subject):
self.name = name
self.subject = subject
def introduce(self):
return f"I am {self.name} and I teach {self.subject}."
hana = Teacher("Hana", "Maths")
soran = Teacher("Soran", "Physics")
print(hana.introduce())
print(soran.introduce())I am Hana and I teach Maths. I am Soran and I teach Physics.
Without running it, write down what this program prints. Then explain each of the four values.
بەبێ کارپێکردنی، بنووسە ئەم چی چاپ دەکات. پاشان هەریەکە لە چوار ڕوون بکەرەوە.
class Student:
def __init__(self, name, grade):
self.name = name
self.grade = grade
a = Student("Rebin", 9)
b = a
b.grade = 10
c = Student("Rebin", 10)
print(a.grade, a is b, a is c, a == c)Show answerوەڵامەکە پیشان بدە
class Student:
def __init__(self, name, grade):
self.name = name
self.grade = grade
a = Student("Rebin", 9)
b = a
b.grade = 10
c = Student("Rebin", 10)
print(a.grade, a is b, a is c, a == c)10 True False False
b = a makes a second name for the same object, so b.grade = 10 changes a.grade too: 10, and a is b is True. c is a new object with the same values, so a is c is False, and a == c is also False, because without __eq__ == compares identity.
b = a ناوێکی دووەم بۆ هەمان دروست دەکات، بۆیە b.grade = 10 a.gradeـیش دەگۆڕێت: 10 و a is b Trueـە. c نوێیە بە هەمان ، بۆیە a is c Falseـە و a == cـیش Falseـە، چونکە بەبێ __eq__، == ناسنامە بەراورد دەکات.
This class has two errors and one style problem. Find all three and write the corrected class.
ئەم دوو هەڵە و کێشەیەکی شێوازی هەیە. هەر سێکیان بدۆزەوە و ڕاستکراوەکە بنووسە.
class course:
def __init__(title, hours):
self.title = title
hours = hours
def describe(self):
return f"{self.title}: {self.hours} hours"
c = course("Python 1", 4)
print(c.describe())Show answerوەڵامەکە پیشان بدە
(1) __init__ has no self, so Python stops at once: TypeError: course.__init__() takes 2 positional arguments but 3 were given. (2) hours = hours stores nothing in the object; after fixing (1), describe() stops with AttributeError: 'course' object has no attribute 'hours'. (3) Style: class names are written in CapWords, Course. The corrected program:
(1) __init__ selfـی نییە، بۆیە یەکسەر دەوەستێت: TypeError: course.__init__() takes 2 positional arguments but 3 were given. (2) hours = hours هیچ شتێک لە هەڵناگرێت؛ دوای چاککردنی (1)، describe() بە AttributeError: 'course' object has no attribute 'hours' دەوەستێت. (3) شێواز: ناوی بە CapWords دەنووسرێن، Course. ڕاستکراوەکە:
class Course:
def __init__(self, title, hours):
self.title = title
self.hours = hours
def describe(self):
return f"{self.title}: {self.hours} hours"
c = Course("Python 1", 4)
print(c.describe())Python 1: 4 hours
Make a list of four Course objects with a title and the hours per week: Python 1 (4), Maths (3), English (2), Physics (3). Print every course with at least 3 hours, then the total hours of all courses.
لە چوار Course دروست بکە بە title و hoursـی هەفتانە: Python 1 (4)، Maths (3)، English (2)، Physics (3). هەموو کۆرسێک کە لانیکەم 3 کاتژمێری هەیە چاپ بکە، پاشان کۆی کاتژمێرەکانی هەموو کۆرسەکان.
Show answerوەڵامەکە پیشان بدە
class Course:
def __init__(self, title, hours):
self.title = title
self.hours = hours # hours per week
courses = [Course("Python 1", 4), Course("Maths", 3), Course("English", 2), Course("Physics", 3)]
total = 0
for c in courses:
total += c.hours
if c.hours >= 3:
print(c.title, c.hours)
print("Total hours:", total)Python 1 4 Maths 3 Physics 3 Total hours: 12
The school library needs a class Book. A new book has a title and is available. borrow() returns "You borrowed …" and marks the book as not available, or returns "… is already borrowed". give_back() makes it available again. Test it by borrowing the same book twice, giving it back and borrowing it again.
کتێبخانەی قوتابخانە پێویستی بە Book هەیە. کتێبێکی نوێ titleـی هەیە و بەردەستە. borrow() "You borrowed …" دەگەڕێنێتەوە و کتێبەکە وەک نابەردەست نیشان دەکات، یان "… is already borrowed" دەگەڕێنێتەوە. give_back() دووپاتە بەردەستی دەکاتەوە. تاقی بکەرەوە: هەمان کتێب دوو جار بخوازە، بیگەڕێنەوە و دووپاتە بیخوازە.
Show answerوەڵامەکە پیشان بدە
class Book:
def __init__(self, title):
self.title = title
self.available = True # every new book is on the shelf
def borrow(self):
if not self.available:
return f"{self.title} is already borrowed"
self.available = False
return f"You borrowed {self.title}"
def give_back(self):
self.available = True
book = Book("Kurdish Poems")
print(book.borrow())
print(book.borrow())
book.give_back()
print(book.borrow())You borrowed Kurdish Poems Kurdish Poems is already borrowed You borrowed Kurdish Poems
available is an instance attribute that the methods read and change: the object remembers its own state between calls.
available کە دەیخوێننەوە و دەیگۆڕن: لە نێوان بانگکردنەکاندا دۆخی خۆی لە بیر دەگرێت.
Summaryپوختە
- Procedural programming keeps data and functions apart; object-oriented programming bundles each piece of data with its actions in an object. Its four ideas: encapsulation, abstraction, inheritance, polymorphism.
- A class is the plan (
class Student:, CapWords); calling it,Student(...), makes an object, an instance of the class. Every Python value is an instance of some class. __init__(self, ...)fills in each new object;self.name = namemakes an instance attribute.selfis the object the method was called on:aram.describe()isStudent.describe(aram).- Read and change attributes with a dot; a misspelt assignment makes a new attribute, and reading a missing one raises
AttributeError.vars()lists them. type(x)gives the class;isinstance(x, C)checks it and also accepts classes built fromC.- Variables, parameters and list items hold references:
b = ashares one object;ischecks identity;copy.copy()makes a new object. - A method is a function in the class with
selffirst; it returns a value or changes the object.__str__returns the textprint()shows.
- و جیا دەهێڵێتەوە؛ هەر پارچە لەگەڵ کارەکانی لە کۆ دەکاتەوە. چوار بیرۆکەکەی: ، ، ، .
- نەخشەکەیە (
class Student:، CapWords)؛ بانگکردنی،Student(...)، دروست دەکات کە . هەموو . __init__(self, ...)هەر نوێ پڕ دەکاتەوە؛self.name = nameدروست دەکات.selfئەو کە لەسەری بانگ کراوە:aram.describe()هەمانStudent.describe(aram)ـە.- بە خاڵ بخوێنەوە و بیانگۆڕە؛ دانانی بە ڕێنووسی هەڵە نوێ دروست دەکات و خوێندنەوەی ون
AttributeErrorدروست دەکات.vars()لیستیان دەکات. type(x)دەدات؛isinstance(x, C)دەیپشکنێت و ئەو قبووڵ دەکات کە لەCدروست کراون.- ، و دانەکانی هەڵدەگرن:
b = aیەک بەش دەکات؛isناسنامە دەپشکنێت؛copy.copy()نوێ دروست دەکات. - لە ناو بە
selfلە پێشەوە؛ دەگەڕێنێتەوە یان دەگۆڕێت.__str__ئەو دەقە دەگەڕێنێتەوە کەprint()پیشانی دەدات.
Next: Attributes and methods: class attributes, more kinds of methods and the special methods __repr__ and __eq__.
داهاتوو: خەسڵەتەکان و میتۆدەکان: ، جۆرەکانی تری و __repr__ و __eq__.
Lesson complete!وانەکە تەواو بوو!
Well done. Review the key terms, then go on to the next lesson.دەستخۆش. سەیرێکی زاراوە سەرەکییەکان بکەرەوە، پاشان بڕۆ بۆ وانەی داهاتوو.
Key termsزاراوە سەرەکییەکان
Attributes and Methodsخەسڵەتەکان و میتۆدەکان
Related lecturesوانە پەیوەندیدارەکان
- Attributes and Methodsخەسڵەتەکان و میتۆدەکان
- Lists, References, Copies and Functionsلیستەکان، ئاماژەکان، کۆپی و کردارەکان
- Variables and Data Typesگۆڕاوەکان و جۆرەکانی دراوە
- Defining and Calling Functionsناساندن و بانگکردنی کردارەکان
- Errors and Debuggingهەڵەکان و کرمەکوژی
- Python Next to JavaPython لە تەنیشت Javaـەوە
- Classes and Objects: Attributes and Methodsکلاسەکان و ئۆبجێکتەکان: تایبەتمەندییەکان و میتۆدەکان
- Constructors, Modifiers and Encapsulationدروستکەرەکان، دیاریکەرەکان و کەپسوولکردن
- Programming Languagesزمانەکانی بەرنامەسازی
- Programming Languages and Algorithmsزمانەکانی بەرنامەسازی و ئەلگۆریزمەکان
- Encapsulation and Propertiesکەپسوولکردن و خەسڵەتە بەڕێوەبراوەکان
- Inheritance and Polymorphismبۆماوە و فرەشێوەیی
References and further readingسەرچاوەکان و خوێندنەوەی زیاتر
- The Python Tutorial, chapter 9: Classes (class definitions, class and instance objects, method objects, self, class and instance variables, random remarks)
- Python Language Reference 3.1: Objects, values and types; 3.3: Special method names (__init__, __repr__, __str__, __eq__, __hash__)
- Python Library: built-in functions isinstance(), type(), id(), repr(), print()
- Python Glossary: attribute, class, method, object, special method, dunder
- PEP 8: Style Guide for Python Code (class names in CapWords, self as the first argument)
- Harvard CS50's Introduction to Programming with Python, Lecture 8: Object-Oriented Programming (notes)
- MIT OpenCourseWare 6.0001 (Fall 2016), Lecture 8: Object Oriented Programming
This lecture is a first edition. The Kurdish text and terminology are waiting for review by Kurdish IT teachers.ئەم وانەیە چاپی یەکەمە. دەقە کوردییەکە و زاراوەکانی چاوەڕێی پێداچوونەوەی مامۆستایانی کوردی بواری IT ن.