python面向对象进阶,对象嵌套,成员修饰符,生成器和迭代器
目录
Day18:面向对象进阶
今日概要:
18.1 成员
18.1.1 变量
18.1.2 方法
18.1.3 属性
18.2 成员修饰符
18.3 对象嵌套
18.4.特殊成员
18.4.1 迭代器、生成器、可迭代对象
Day18:面向对象进阶 今日概要:
方法
属性
基于方法+property装饰器实现可以实现,可以实现 - obj.属性名 - obj.属性名 = 123 - del obj.属性名 语法和方法的对应关系。
成员修饰符(公有/私有)
对象嵌套:把一个已经实例化的对象,当成参数传进另一个类中
特殊成员:方法都是__方法__格式,这种方法在内部均有特殊的含义
18.1 成员
面向对象中的所有成员如下:
方法
属性 -->
18.1.1 变量
class Person(object):country = "中国"
def __init__(self, name, age):self.name = nameself.age = age
def show(self):# message = "{}-{}-{}".format(Person.country, self.name, self.age)message = "{}-{}-{}".format(self.country, self.name, self.age)print(message)
print(Person.country) # 中国
p1 = Person("大烧饼",20)
print(p1.name)
print(p1.age)
print(p1.country) # 中国
p1.show() # 中国-大烧饼-20
提示:当每个对象中都存在的相同的实例变量时,可以选择把它放在类变量中,这样就可以避免对象中维护多个相同数据。
18.1.2 方法
class Foo(object):
def __init__(self, name,age):self.name = nameself.age = age
def f1(self):print("绑定方法", self.name)
@classmethoddef f2(cls):print("类方法", cls)
@staticmethoddef f3():print("静态方法")# 绑定方法(对象)
obj = Foo("大烧饼",20)
obj.f1() # Foo.f1(obj)--> 类调用方法需要手动传入参数self
# 类方法
Foo.f2() # cls就是当前调用这个方法的类。(类)
obj.f2() # cls就是当前调用这个方法的对象的类。
# 静态方法
Foo.f3() # 类直接执行方法(类)
obj.f3() # 对象直接执行方法
在中比较灵活,方法都可以通过对象和类进行调用;而在java、c#等语言中,绑定方法只能由对象调用;类方法或静态方法只能由类调用。
选择方面:
18.1.3 属性
不是非他不可,不是特别重要,没有他不太影响,锦上添花作用。
属性其实是由绑定方法 + 特殊装饰器 组合创造出来的,让我们以后在调用方法时可以不加括号,例如:
class Foo(object):
def __init__(self, name):self.name = name
def f1(self):return 123
@propertydef f2(self):return 123
obj = Foo("大烧饼")
v1 = obj.f1()
print(v1)
v2 = obj.f2 # 加上 @property 执行可以不加括号
print(v2)
属性补充:
由于属性和实例变量的调用方式相同,所以在编写时需要注意:属性名称 不要 实例变量 重名。
一旦重名,可能就会有报错。
class Foo(object):
def __init__(self, name, age):self.name = name # 报错,错认为你想要调用 @name.setter 装饰的方法。self.age = age
@propertydef name(self): # namereturn "{}-{}".format(self.name, self.age)
obj = Foo("大烧饼", 123)
如果真的想要在名称上创建一些关系,可以让实例变量加上一个下划线。
class Foo(object):
def __init__(self, name, age):self._name = nameself.age = age
@propertydef name(self):return "{}-{}".format(self._name, self.age)
obj = Foo("大烧饼", 123)
print(obj._name)
print(obj.name)
18.2 成员修饰符
中成员的修饰符就是指的是:公有、私有。
示例一:
class Foo(object):
def __init__(self, name, age):self.__name = nameself.age = age
def get_data(self):return self.__name
def get_age(self):return self.age
obj = Foo("大烧饼", 123)
# 公有成员
print(obj.age)
v1 = self.get_age()
print(v1)
# 私有成员
# print(obj.__name) # 错误,由于是私有成员,只能在类中进行使用。
v2 = obj.get_data()
print(v2)
特别提醒:父类中的私有成员,子类无法继承。
class Base(object):
def __data(self):print("base.__data")
def num(self):print("base.num")
class Foo(Base):
def func(self):self.num()self.__data() # # 不允许执行父类中的私有方法
obj = Foo()
obj.func()
成员是否可以作为独立的功能暴露给外部,让外部调用并使用。
18.3 对象嵌套
在基于面向对象进行编程时,对象之间可以存在各种各样的关系,例如:组合、关联、依赖等(Java中的称呼),用大白话来说就是各种嵌套。
下面我们就用示例来学习常见的嵌套的情景:
情景一:
class Student(object):""" 学生类 """
def __init__(self, name, age):self.name = nameself.age = age
def message(self):data = "我是一名学生,我叫:{},我今年{}岁".format(self.name, self.age)print(data)
s1 = Student("大烧饼", 19)
s2 = Student("abcd", 19)
s3 = Student("日天", 19)
class Classes(object):""" 班级类 """
def __init__(self, title):self.title = title # self.title = "三年二班"self.student_list = []
def add_student(self, stu_object):self.student_list.append(stu_object)
def add_students(self, stu_object_list):for stu in stu_object_list:self.add_student(stu)
def show_members(self):for item in self.student_list:# print(item)item.message()
c1 = Classes("三年二班") # s1 s2 s3
c1.add_student(s1) # self.student_list[self,self,self]
c1.add_students([s2, s3])
c1.show_members()
情景三:
class Student(object):""" 学生类 """
def __init__(self, name, age, class_object):self.name = nameself.age = ageself.class_object = class_object
def message(self):data = "我是一名{}班的学生,我叫:{},我今年{}岁".format(self.class_object.title, self.name, self.age)print(data)
class Classes(object):""" 班级类 """
def __init__(self, title, school_object):self.title = titleself.school_object = school_object
class School(object):""" 学校类 """
def __init__(self, name):self.name = name
s1 = School("北京校区")
s2 = School("上海校区")
c1 = Classes("Python全栈", s1)
c2 = Classes("Linux云计算", s2)
user_object_list = [Student("大烧饼", 19, c1),Student("abcd", 19, c1),Student("日天", 19, c2)
]
for obj in user_object_list:print(obj.name, obj.class_object.title , obj.class_object.school_object.name)
18.4.特殊成员
在的类中存在一些特殊的方法,这些方法都是 __方法__ 格式,这种方法在内部均有特殊的含义,接下来我们来讲一些常见的特殊成员:
18.4.1 迭代器、生成器、可迭代对象
迭代器:含有方法和方法,返回自身,可以获取数据(终止是抛出异常。可以被for循环。
生成器:在定义时是函数中重要包含yield就是生成器函数,执行函数获得生成器对象(一种特殊的迭代器);可以通过next取值 & 也可以通过for循环取值。
可迭代对象:含有方法,且返回一个迭代器对象。可以被for循环。