您当前的位置:首页 > IT编程 > python
| C语言 | Java | VB | VC | python | Android | TensorFlow | C++ | oracle | 学术与代码 | cnn卷积神经网络 | gnn | 图像修复 | Keras | 数据集 | Neo4j | 自然语言处理 | 深度学习 | 医学CAD | 医学影像 | 超参数 | pointnet | pytorch | 异常检测 | Transformers | 情感分类 | 知识图谱 |

自学教程:Python面向对象之成员相关知识总结

51自学网 2021-10-30 22:26:43
  python
这篇教程Python面向对象之成员相关知识总结写得很实用,希望能帮到您。

一、成员

 1.1 变量

  • 实例变量,属于对象,每个对象中各自维护自己的数据。
  • 类变量,属于类,可以被所有对象共享,一般用于给对象提供公共数据(类似于全局变量)。
class Person(object):    country = "中国"     def __init__(self, name, age):        self.name = name        self.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

提示:当把每个对象中都存在的相同的示例变量时,可以选择把它放在类变量中,这样就可以避免对象中维护多个相同数据。

易错点

  • 注意读和写的区别。
class Person(object):    country = "中国"     def __init__(self, name, age):        self.name = name        self.age = age     def show(self):        message = "{}-{}-{}".format(self.country, self.name, self.age)        print(message) print(Person.country) # 中国 p1 = Person("华青水上",20)print(p1.name) # 华青水上print(p1.age) # 20print(p1.country) # 中国p1.show() # 中国-华青水上-20 p1.name = "root"     # 在对象p1中讲name重置为rootp1.num = 19          # 在对象p1中新增实例变量 num=19p1.country = "china" # 在对象p1中新增实例变量 country="china" print(p1.country)   # chinaprint(Person.country) # 中国
class Person(object):    country = "中国"     def __init__(self, name, age):        self.name = name        self.age = age     def show(self):        message = "{}-{}-{}".format(self.country, self.name, self.age)        print(message) print(Person.country) # 中国 Person.country = "美国"  p1 = Person("华青水上",20)print(p1.name) # 华青水上print(p1.age) # 20print(p1.country) # 美国
  • 继承关系中的读写
class Base(object):    country = "中国"  class Person(Base):     def __init__(self, name, age):        self.name = name        self.age = age     def show(self):        message = "{}-{}-{}".format(Person.country, self.name, self.age)        # message = "{}-{}-{}".format(self.country, self.name, self.age)        print(message)  # 读print(Base.country) # 中国print(Person.country) # 中国 obj = Person("华青水上",19)print(obj.country) # 中国 # 写Base.country = "china"Person.country = "泰国"obj.country = "日本"

1.2 方法

  • 绑定方法,默认有一个self参数,由对象进行调用(此时self就等于调用方法的这个对象)【对象&类均可调用】
  • 类方法,默认有一个cls参数,用类或对象都可以调用(此时cls就等于调用方法的这个类)【对象&类均可调用】
  • 静态方法,无默认参数,用类和对象都可以调用。【对象&类均可调用】
class Foo(object):     def __init__(self, name,age):        self.name = name        self.age = age     def f1(self):        print("绑定方法", self.name)     @classmethod    def f2(cls):        print("类方法", cls)     @staticmethod    def f3():        print("静态方法")        # 绑定方法(对象)obj = Foo("武沛齐",20)obj.f1() # Foo.f1(obj)  # 类方法Foo.f2()  # cls就是当前调用这个方法的类。(类)obj.f2()  # cls就是当前调用这个方法的对象的类。  # 静态方法Foo.f3()  # 类执行执行方法(类)obj.f3()  # 对象执行执行方法

在Python中比较灵活,方法都可以通过对象和类进行调用;而在java、c#等语言中,绑定方法只能由对象调用;类方法或静态方法只能由类调用。

import osimport requests  class Download(object):     def __init__(self, folder_path):        self.folder_path = folder_path     @staticmethod    def download_dou_yin():        # 下载抖音        res = requests.get('.....')         with open("xxx.mp4", mode='wb') as f:            f.write(res.content)     def download_dou_yin_2(self):        # 下载抖音        res = requests.get('.....')        path = os.path.join(self.folder_path, 'xxx.mp4')        with open(path, mode='wb') as f:            f.write(res.content)  obj = Download("video")obj.download_dou_yin()

1.3 属性

属性其实是由绑定方法 + 特殊装饰器 组合创造出来的,让我们以后在调用方法时可以不加括号。

class Foo(object):     def __init__(self, name):        self.name = name     def f1(self):        return 123     @property    def f2(self):        return 123  obj = Foo("华青水上") v1 = obj.f1()print(v1) v2 = obj.f2print(v2)
class Pagination:    def __init__(self, current_page, per_page_num=10):        self.per_page_num = per_page_num                if not current_page.isdecimal():            self.current_page = 1            return        current_page = int(current_page)        if current_page < 1:            self.current_page = 1            return        self.current_page = current_page	    def start(self):        return (self.current_page - 1) * self.per_page_num	    def end(self):        return self.current_page * self.per_page_num  user_list = ["用户-{}".format(i) for i in range(1, 3000)] # 分页显示,每页显示10条while True:    page = input("请输入页码:")	    # page,当前访问的页码    # 10,每页显示10条数据	# 内部执行Pagination类的init方法。    pg_object = Pagination(page, 20)        page_data_list = user_list[ pg_object.start() : pg_object.end() ]    for item in page_data_list:        print(item)
class Pagination:    def __init__(self, current_page, per_page_num=10):        self.per_page_num = per_page_num         if not current_page.isdecimal():            self.current_page = 1            return        current_page = int(current_page)        if current_page < 1:            self.current_page = 1            return        self.current_page = current_page     @property    def start(self):        return (self.current_page - 1) * self.per_page_num     @property    def end(self):        return self.current_page * self.per_page_num  user_list = ["用户-{}".format(i) for i in range(1, 3000)] # 分页显示,每页显示10条while True:    page = input("请输入页码:")     pg_object = Pagination(page, 20)    page_data_list = user_list[ pg_object.start : pg_object.end ]        for item in page_data_list:        print(item)

关于属性的编写有两种方式:

  • 方式一,基于装饰器
class C(object):        @property    def x(self):        pass        @x.setter    def x(self, value):        pass        @x.deleter    def x(self):		pass        obj = C() obj.xobj.x = 123del obj.x
  • 方式二,基于定义变量
class C(object):        def getx(self): 		pass        def setx(self, value): 		pass            def delx(self): 		pass            x = property(getx, setx, delx, "I'm the 'x' property.")    obj = C() obj.xobj.x = 123del obj.x

注意:由于属性和实例变量的调用方式相同,所以在编写时需要注意:属性名称 不要 实例变量 重名。

class Foo(object):     def __init__(self, name, age):        self.name = name        self.age = age     @property    def func(self):        return 123  obj = Foo("华青水上", 123)print(obj.name)

一旦重名,可能就会有报错。

class Foo(object):     def __init__(self, name, age):        self.name = name  # 报错,错认为你想要调用 @name.setter 装饰的方法。        self.age = age     @property    def name(self):        return "{}-{}".format(self.name, self.age)  obj = Foo("华青水上", 123)
class Foo(object):     def __init__(self, name, age):        self.name = name         self.age = age     @property    def name(self):        return "{}-{}".format(self.name, self.age) # 报错,循环调用自己(直到层级太深报错)     @name.setter    def name(self, value):        print(value)  obj = Foo("华青水上", 123)print(obj.name)

如果真的想要在名称上创建一些关系,可以让实例变量加上一个下划线。

class Foo(object):     def __init__(self, name, age):        self._name = name        self.age = age     @property    def name(self):        return "{}-{}".format(self._name, self.age)  obj = Foo("华青水上", 123)print(obj._name)print(obj.name)

二、成员修饰符

Python中成员的修饰符就是指的是:公有、私有。

  • 公有,在任何地方都可以调用这个成员。
  • 私有,只有在类的内部才可以调用改成员(成员是以两个下划线开头,则表示该成员为私有)。
class Foo(object):     def __init__(self, name, age):        self.__name = name        self.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()
class Base(object):     def __data(self):        print("base.__data")     def num(self):        print("base.num")        self.__data()  # 不允许执行父类中的私有方法  class Foo(Base):     def func(self):        self.num()  obj = Foo()obj.func()

按理说私有成员是无法被外部调用,但如果用一些特殊的语法也可以(Flask源码中有这种写法,大家写代码不推荐这样写)。

class Foo(object):     def __init__(self):        self.__num = 123        self.age = 19     def __msg(self):        print(1234)  obj = Foo()print(obj.age)print(obj._Foo__num)obj._Foo__msg()

成员是否可以作为独立的功能暴露给外部,让外部调用并使用。

  • 可以,公有。
  • 不可以,内部其他放的一个辅助,私有。

三、对象嵌套

在基于面向对象进行编程时,对象之间可以存在各种各样的关系,例如:组合、关联、依赖等(Java中的称呼),用大白话来说就是各种嵌套。

情景一:

class Student(object):    """ 学生类 """     def __init__(self, name, age):        self.name = name        self.age = age     def message(self):        data = "我是一名学生,我叫:{},我今年{}岁".format(self.name, self.age)        print(data) s1 = Student("华青水上", 19)s2 = Student("殊途同归", 19)s3 = Student("春花秋月", 19)   class Classes(object):    """ 班级类 """     def __init__(self, title):        self.title = 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("三年二班")c1.add_student(s1)c1.add_students([s2, s3]) print(c1.title)print(c1.student_list)

情景二:

class Student(object):    """ 学生类 """     def __init__(self, name, age, class_object):        self.name = name        self.age = age        self.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):        self.title = title  c1 = Classes("Python全栈")c2 = Classes("Linux云计算")  user_object_list = [    Student("华青水上", 19, c1),    Student("殊途同归", 19, c1),    Student("春花秋月", 19, c2)] for obj in user_object_list:    print(obj.name,obj.age, obj.class_object.title)

情景三:

class Student(object):    """ 学生类 """     def __init__(self, name, age, class_object):        self.name = name        self.age = age        self.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 = title        self.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("殊途同归", 19, c1),    Student("春花秋月", 19, c2)]for obj in user_object_list:    print(obj.name, obj.class_object.title ,  obj.class_object.school_object.name)

四、特殊成员

在Python的类中存在一些特殊的方法,这些方法都是 __方法__ 格式,这种方法在内部均有特殊的含义,接下来我们来讲一些常见的特殊成员:

  • __init__,初始化方法
class Foo(object):    def __init__(self, name):        self.name = name  obj = Foo("华青水上")
  • __new__,构造方法
class Foo(object):    def __init__(self, name):        print("第二步:初始化对象,在空对象中创建数据")        self.name = name     def __new__(cls, *args, **kwargs):        print("第一步:先创建空对象并返回")        return object.__new__(cls)  obj = Foo("华青水上")
  • __call__
class Foo(object):    def __call__(self, *args, **kwargs):        print("执行call方法")  obj = Foo()obj()
  • __str__
class Foo(object):     def __str__(self):        return "哈哈哈哈"  obj = Foo()data = str(obj)print(data)
  • __dict__
class Foo(object):    def __init__(self, name, age):        self.name = name        self.age = age  obj = Foo("华青水上",19)print(obj.__dict__)
  • __getitem____setitem____delitem__
class Foo(object):     def __getitem__(self, item):        pass     def __setitem__(self, key, value):        pass     def __delitem__(self, key):        pass  obj = Foo("华青水上", 19) obj["x1"]obj['x2'] = 123del obj['x3']
  • __enter____exit__
class Foo(object):     def __enter__(self):        print("进入了")        return 666     def __exit__(self, exc_type, exc_val, exc_tb):        print("出去了")  obj = Foo()with obj as data:    print(data)

# 面试题(补充代码,实现如下功能)

class Context:     def __enter__(self):        return self             def __exit__(self, exc_type, exc_val, exc_tb):        pass     def do_something(self):      # __enter__返回self才可以调用执行do_something方法        pass  with Context() as ctx:    ctx.do_something()

上述面试题属于上下文管理的语法

  • __add__
class Foo(object):    def __init__(self, name):        self.name = name     def __add__(self, other):        return "{}-{}".format(self.name, other.name)  v1 = Foo("alex")v2 = Foo("sb") # 对象+值,内部会去执行 对象.__add__方法,并将+后面的值当做参数传递过去。v3 = v1 + v2print(v3)
  • __iter__

迭代器

# 迭代器类型的定义:    1.当类中定义了 __iter__ 和 __next__ 两个方法。    2.__iter__ 方法需要返回对象本身,即:self    3. __next__ 方法,返回下一个数据,如果没有数据了,则需要抛出一个StopIteration的异常。	官方文档:https://docs.python.org/3/library/stdtypes.html#iterator-types        # 创建 迭代器类型 :	class IT(object):        def __init__(self):            self.counter = 0         def __iter__(self):            return self         def __next__(self):            self.counter += 1            if self.counter == 3:                raise StopIteration()            return self.counter # 根据类实例化创建一个迭代器对象:    obj1 = IT()        # v1 = obj1.__next__()    # v2 = obj1.__next__()    # v3 = obj1.__next__() # 抛出异常        v1 = next(obj1) # obj1.__next__()    print(v1)     v2 = next(obj1)    print(v2)     v3 = next(obj1)    print(v3)      obj2 = IT()    for item in obj2:  # 首先会执行迭代器对象的__iter__方法并获取返回值,一直去反复的执行 next(对象)         print(item)    

迭代器对象支持通过next取值,如果取值结束则自动抛出StopIteration。

for循环内部在循环时,先执行__iter__方法,获取一个迭代器对象,然后不断执行的next取值(有异常StopIteration则终止循环)。

生成器

# 创建生成器函数    def func():        yield 1        yield 2    # 创建生成器对象(内部是根据生成器类generator创建的对象),生成器类的内部也声明了:__iter__、__next__ 方法。    obj1 = func()        v1 = next(obj1)    print(v1)     v2 = next(obj1)    print(v2)     v3 = next(obj1)    print(v3)      obj2 = func()    for item in obj2:        print(item)

如果按照迭代器的规定来看,其实生成器类也是一种特殊的迭代器类(生成器也是一个中特殊的迭代器)。

可迭代对象

# 如果一个类中有__iter__方法且返回一个迭代器对象 ;则我们称以这个类创建的对象为可迭代对象。 class Foo(object):        def __iter__(self):        return 迭代器对象(生成器对象)    obj = Foo() # obj是 可迭代对象。 # 可迭代对象是可以使用for来进行循环,在循环的内部其实是先执行 __iter__ 方法,获取其迭代器对象,然后再在内部执行这个迭代器对象的next功能,逐步取值。for item in obj:    pass

可迭代对象是可以使用for来进行循环,在循环的内部其实是先执行 __iter__ 方法,获取其迭代器对象,然后再在内部执行这个迭代器对象的next功能,逐步取值。

class IT(object):    def __init__(self):        self.counter = 0     def __iter__(self):        return self     def __next__(self):        self.counter += 1        if self.counter == 3:            raise StopIteration()        return self.counter  class Foo(object):    def __iter__(self):        return IT()  obj = Foo() # 可迭代对象  for item in obj: # 循环可迭代对象时,内部先执行obj.__iter__并获取迭代器对象;不断地执行迭代器对象的next方法。    print(item)
# 基于可迭代对象&迭代器实现:自定义rangeclass IterRange(object):    def __init__(self, num):        self.num = num        self.counter = -1     def __iter__(self):        return self     def __next__(self):        self.counter += 1        if self.counter == self.num:            raise StopIteration()        return self.counter  class Xrange(object):    def __init__(self, max_num):        self.max_num = max_num     def __iter__(self):        return IterRange(self.max_num)  obj = Xrange(100) for item in obj:    print(item)
class Foo(object):    def __iter__(self):        yield 1        yield 2  obj = Foo()for item in obj:    print(item)
# 基于可迭代对象&生成器 实现:自定义range class Xrange(object):    def __init__(self, max_num):        self.max_num = max_num     def __iter__(self):        counter = 0        while counter < self.max_num:            yield counter            counter += 1  obj = Xrange(100)for item in obj:    print(item)

常见的数据类型:

from collections.abc import Iterator, Iterable v1 = [11, 22, 33]print( isinstance(v1, Iterator) )  # false,判断是否是迭代器;判断依据是__iter__ 和 __next__。v2 = v1.__iter__()print( isinstance(v2, Iterator) )  # True   v1 = [11, 22, 33]print( isinstance(v1, Iterable) )  # True,判断依据是是否有 __iter__且返回迭代器对象。 v2 = v1.__iter__()print( isinstance(v2, Iterable) )  # True,判断依据是是否有 __iter__且返回迭代器对象。

至此,Python进阶面向对象之成员总结完毕,如有不当之处欢迎指正。

到此这篇关于Python面向对象之成员相关知识总结的文章就介绍到这了,更多相关Python成员内容请搜索51zixue.net以前的文章或继续浏览下面的相关文章希望大家以后多多支持51zixue.net!


Python面向对象之内置函数相关知识总结
详解Python为什么不用设计模式
万事OK自学网:51自学网_软件自学网_CAD自学网自学excel、自学PS、自学CAD、自学C语言、自学css3实例,是一个通过网络自主学习工作技能的自学平台,网友喜欢的软件自学网站。