类和对象
Python是一种面向对象的编程语言。Python中的一切都是对象,带有它们各自的属性和方法。程序中使用的数字、字符串、列表、字典、元组、集合等都是相应内置类的对象。我们创建类来创建对象。类就像是对象构造器或是创建对象的"蓝图"。我们实例化一个类来创建一个对象。类定义了对象的属性和行为,而对象则代表类。
我们在不知不觉中从这个挑战的一开始就一直在使用类和对象。Python程序中的每个元素都是一个类的对象。让我们来验证下Python中是否每个东西都是类:
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> num = 10
>>> type(num)
<class 'int'>
>>> string = 'string'
>>> type(string)
<class 'str'>
>>> boolean = True
>>> type(boolean)
<class 'bool'>
>>> lst = []
>>> type(lst)
<class 'list'>
>>> tpl = ()
>>> type(tpl)
<class 'tuple'>
>>> set1 = set()
>>> type(set1)
<class 'set'>
>>> dct = {}
>>> type(dct)
<class 'dict'>
创建一个类
创建类需要关键词"class",紧接着是名称和冒号。类名应该是驼峰式的。
# 语法
class ClassName:
代码块
示例:
class Person:
pass
print(Person)
<__main__.Person object at 0x10804e510>
创建对象
我们可以通过调用类来创建对象。
p = Person()
print(p)
类构造函数
在上面的例子中,我们已经从Person类创建了一个对象。但是,一个没有构造函数的类在真实应用程序中并没有什么用处。让我们使用构造函数来使我们的类更有用。像Java或JavaScript中的构造函数一样,Python也有一个内置的init()构造函数。init构造函数具有self参数,该参数是对类的当前实例的引用。例子:
class Person:
def __init__ (self, name):
# self allows to attach parameter to the class
self.name =name
p = Person('Asabeneh')
print(p.name)
print(p)
# 输出
Asabeneh
<__main__.Person object at 0x2abf46907e80>
让我们为构造函数添加更多的参数。
class Person:
def __init__(self, firstname, lastname, age, country, city):
self.firstname = firstname
self.lastname = lastname
self.age = age
self.country = country
self.city = city
p = Person('Asabeneh', 'Yetayeh', 250, 'Finland', 'Helsinki')
print(p.firstname)
print(p.lastname)
print(p.age)
print(p.country)
print(p.city)
# 输出
Asabeneh
Yetayeh
250
Finland
Helsinki
对象方法
对象可以有方法。这些方法是属于对象的函数。
示例:
class Person:
def __init__(self, firstname, lastname, age, country, city):
self.firstname = firstname
self.lastname = lastname
self.age = age
self.country = country
self.city = city
def person_info(self):
return f'{self.firstname} {self.lastname} is {self.age} years old. He lives in {self.city}, {self.country}'
p = Person('Asabeneh', 'Yetayeh', 250, 'Finland', 'Helsinki')
print(p.person_info())
# 输出
Asabeneh Yetayeh is 250 years old. He lives in Helsinki, Finland
对象默认方法
有时候,你可能希望对象方法有默认值。如果我们在构造函数的参数中设置了默认值,那么我们在调用或实例化该类时就可以避免错误。让我们看看它是什么样子:
示例:
class Person:
def __init__(self, firstname='Asabeneh', lastname='Yetayeh', age=250, country='Finland', city='Helsinki'):
self.firstname = firstname
self.lastname = lastname
self.age = age
self.country = country
self.city = city
def person_info(self):
return f'{self.firstname} {self.lastname} is {self.age} years old. He lives in {self.city}, {self.country}.'
p1 = Person()
print(p1.person_info())
p2 = Person('John', 'Doe', 30, 'Nomanland', 'Noman city')
print(p2.person_info())
# 输出
Asabeneh Yetayeh is 250 years old. He lives in Helsinki, Finland.
John Doe is 30 years old. He lives in Noman city, Nomanland.
修改类的默认值的方法
在下面的示例中,人类所有构造函数参数都有默认值。除此之外,我们有技能参数,可以使用方法访问。让我们创建add_skill方法,将技能添加到技能列表中。
class Person:
def __init__(self, firstname='Asabeneh', lastname='Yetayeh', age=250, country='Finland', city='Helsinki'):
self.firstname = firstname
self.lastname = lastname
self.age = age
self.country = country
self.city = city
self.skills = []
def person_info(self):
return f'{self.firstname} {self.lastname} is {self.age} years old. He lives in {self.city}, {self.country}.'
def add_skill(self, skill):
self.skills.append(skill)
p1 = Person()
print(p1.person_info())
p1.add_skill('HTML')
p1.add_skill('CSS')
p1.add_skill('JavaScript')
p2 = Person('John', 'Doe', 30, 'Nomanland', 'Noman city')
print(p2.person_info())
print(p1.skills)
print(p2.skills)
# 输出
Asabeneh Yetayeh is 250 years old. He lives in Helsinki, Finland.
John Doe is 30 years old. He lives in Noman city, Nomanland.
['HTML', 'CSS', 'JavaScript']
[]
继承
使用继承可以重用父类代码。继承允许我们定义一个从父类继承所有方法和属性的类。父类或超类或基类是提供所有方法和属性的类。子类是从另一个或父类继承的类。让我们通过从Person继承来创建一个Student类。
class Student(Person):
pass
s1 = Student('Eyob', 'Yetayeh', 30, 'Finland', 'Helsinki')
s2 = Student('Lidiya', 'Teklemariam', 28, 'Finland', 'Espoo')
print(s1.person_info())
s1.add_skill('JavaScript')
s1.add_skill('React')
s1.add_skill('Python')
print(s1.skills)
print(s2.person_info())
s2.add_skill('Organizing')
s2.add_skill('Marketing')
s2.add_skill('Digital Marketing')
print(s2.skills)
# 输出
Eyob Yetayeh is 30 years old. He lives in Helsinki, Finland.
['JavaScript', 'React', 'Python']
Lidiya Teklemariam is 28 years old. He lives in Espoo, Finland.
['Organizing', 'Marketing', 'Digital Marketing']
我们没有在子类中调用init()构造函数。如果我们没有调用它,那么我们仍然可以访问父类中的所有属性。但是如果我们调用构造函数, 我们可以通过调用super来访问父类属性。
我们可以为子类添加一个新的方法,或者通过在子类中创建相同的方法名称来覆盖父类的方法。当我们添加init()函数时,子类将不再继承父类的init()函数。
覆盖父类方法
class Student(Person):
def __init__ (self, firstname='Asabeneh', lastname='Yetayeh',age=250, country='Finland', city='Helsinki', gender='male'):
self.gender = gender
super().__init__(firstname, lastname,age, country, city)
def person_info(self):
gender = 'He' if self.gender =='male' else 'She'
return f'{self.firstname} {self.lastname} is {self.age} years old. {gender} lives in {self.city}, {self.country}.'
s1 = Student('Eyob', 'Yetayeh', 30, 'Finland', 'Helsinki','male')
s2 = Student('Lidiya', 'Teklemariam', 28, 'Finland', 'Espoo', 'female')
print(s1.person_info())
s1.add_skill('JavaScript')
s1.add_skill('React')
s1.add_skill('Python')
print(s1.skills)
print(s2.person_info())
s2.add_skill('Organizing')
s2.add_skill('Marketing')
s2.add_skill('Digital Marketing')
print(s2.skills)
Eyob Yetayeh is 30 years old. He lives in Helsinki, Finland.
['JavaScript', 'React', 'Python']
Lidiya Teklemariam is 28 years old. She lives in Espoo, Finland.
['Organizing', 'Marketing', 'Digital Marketing']
我们可以使用super()内置函数或父类名称Person来自动继承其父类的方法和属性。在上面的例子中,我们覆盖了父类的方法。子类方法具有不同的特点,可以确定性别是男性还是女性,并分配正确的代词(He/She)。
评论区