0
点赞
收藏
分享

微信扫一扫

python入门基础04——面向对象、链表、异常处理

未定义变量 2022-01-13 阅读 35

文章目录

面向对象

class 类名():# 类名首字母一般大写
    pass

实例变量和类变量

class Animal():
    # 构造方法,在创建对象的时候被自动调用
    def __init__(self, name, age):
        # 实例变量
        self.name = name
        self.age = age
        print('xxx')


dog1 = Animal('dog1', 1)  # Animal()实际上是调用init方法
print(dog1.name, dog1.age)
dog2 = Animal('dog2', 2)
print(dog2.name, dog2.age)
class Student:
    classroom = '101'  # 类变量
    address = 'anhui'

    def __init__(self, name, age):
        # 实例变量
        self.name = name
        self.age = age

    def print_age(self):
        print('%s %s' % (self.name, self.age))


student = Student('xiao', 22)
print(Student.address)

self

class Student:
    classroom = '101'  # 类变量
    address = 'anhui'

    def __init__(self, name, age):
        # 实例变量
        print(self)
        self.name = name
        self.age = age

    def print_age(self):
        print('%s %s' % (self.name, self.age))

    def study(self, course):
        print(self) # self 就是当前study的调用者
        print('我在学习%s' % course)
        self.func() # self表示实例对象

    def func(self):
        print('func')


student1 = Student('xiao', 22)
student2 = Student('xiao', 22)
print(student1)
student1.study('代数')


# self在不同位置将不一样,相对值,cls也是一样
class Father():
    def get_some(self):
        print(self)


class Son(Father):
    pass


f = Father()
f.get_some()
s = Son()
s.get_some()

结果:
<__main__.Father object at 0x0000025CE655C548>
<__main__.Son object at 0x0000025CE655C348>

类的方法

类方法

# 类的方式由类调用,采用classmethod装饰,至少传入一个cls(类似self)参数
# 同于类变量,类方法被共享
class Studnet():
    def __init__(self):
        pass

    @classmethod  # 装饰器
    def c_func(cls):
        print('类方法',cls)


print(Studnet)
Studnet.c_func()

# 类方法中是否可以调实例方法和实例变量?
不能,因为实例变量和实例方法只能通过对象名访问,但是在类方法内部不存在对象名
# 在实例方法中是否可以调类方法和类变量

静态方法

# 不属于实例也不属于类,只是定义在类中普通方法,staticmethod修饰
class Studnet():
    def __init__(self):
        pass

    def study(self):  # 实例方法
        self.c_func()
        print('学不死就往死学')

    @classmethod  # 装饰器
    def c_func(cls):
        # cls.study(cls)
        print('类方法', cls)

    @staticmethod
    def func():
        print('静态')


print(Studnet)
Studnet().study()
Studnet.c_func()
Studnet.func()

对象关联关系

封装、继承、多态

class Father():  # 父类
    address = 'NJ'

    def __init__(self):
        self.var = 'xxx'
        print('父类构造方法')

    def hobby(self):
        print("撸铁")

    @classmethod
    def class_method(cls):
        print('father类类方法')

    @staticmethod
    def static_method():
        print('father静态方法')


class Son(Father):  # 子类
    pass


son = Son()
print(son.var)  # 子类继承父类实例变量
son.hobby()  # 子类可继承父类实例方法
print(son.address)  # 子类可继承父类的类变量
son.class_method()  # 子类可继承父类的类方法
son.static_method()  # 子类可继承父类的静态方法


结果:
父类构造方法
xxx
撸铁
NJ
father类类方法
father静态方法

派生

class Father():
    def hobby(self):
        print('撸铁')


class Son(Father):
    def hobby(self):  # 没有部分重写就是完全重写
        super().hobby()  # 部分重写
        print("撸code")


s = Son()
s.hobby()

多父类

# 有继承优先级,越靠前优先选择
class Father1():
    def hobby(self):
        print('撸铁1哥')


class Father2():
    def hobby(self):
        print('撸铁2哥')


class Son(Father1, Father2):
    def hobby(self):
        super().hobby()
        print("撸code")


son = Son()
son.hobby()

结果:
撸铁1哥
撸code

type和isinstance

# type之前使用过,不赘述,就是返回对象的类型
# isinstance和type区别:
# type不会认为子类是一种父类类型,不考虑继承关系
# isinstance会认为子类是一种父类类型,考虑继承关系
print(isinstance(son, int)) //False
print(isinstance(son, Son)) //True
print(isinstance(son, Father1)) //True

new方法和self

class stu():
    def __init__(self):
        print('init方法')
    
    # 重写父类的方法
    def __new__(self):
        print('new方法')

s = stu() # 对象不会被创建,只会输出__new__中方法
# 注意,python中创建对象后,会自动调用___init__方法给对象赋属性,如果没有调init方法,则对象创建失败
class stu():
    def __init__(self):
        print('init方法')
    
    # 重写父类的方法
    def __new__(self): 
        print('new方法')
        # 返回给了所有实例方法第一个参数self
        return super().__new__(self) # self赋值

s = stu() # 对象创建成功

# 例子
class Classroom(object):
    count = 0

    @classmethod
    def show_count(cls):
        print("现有人数为%s" % cls.count)

    @classmethod
    def add_count(cls):
        cls.count += 1

    def __new__(cls, *args, **kwargs):
        Classroom.add_count()  # 不可使用cls,这样的话是使用子类本身
        return super().__new__(cls)

class Student(Classroom):
    pass

s1 = Student()
s2 = Student()
s3 = Student()
Classroom.show_count()

结果:现有人数为3

成员保护和访问限制

反射

class Teacher():
    age = 22

    def __init__(self):
        self.name = 'xiao'

    def study(self):
        print('study')


r1 = hasattr(Teacher, 'age')  # 判断该类是否存在该成员变量/方法
print(r1) # True

t = Teacher()
r2 = getattr(Teacher, 'study')  # 拿到该类的成员变量/方法
r2(t) # study

单例模式

class Singleton():

    def __new__(cls, *args, **kwargs):
        if not hasattr(Singleton, 'instance'):
            # cls.instance 相对指向,指本身,但子类不是单例
            # 类名.instance 就是专门指定的类,所以子类也是单例
            Singleton.instance = super().__new__(cls)
        return Singleton.instance


class Sig(Singleton):
    pass


s1 = Singleton()
s2 = Singleton()
print(id(s1), id(s2))

ss1 = Sig()
ss2 = Sig()
print(id(ss1), id(ss2))

链表

class Node:
    def __init__(self, item):
        self.item = item
        self.next = None


class Link:
    def __init__(self):
        self.head = None  # 指向第一个节点

    def addHead(self, item):
        """
        插入节点
        :param item:
        :return:
        """
        node = Node(item)  # 获取一个节点
        node.next = self.head  # 将获取的节点的next指向之前的节点
        self.head = node  # 将获取的节点作为头节点

    def travel(self):
        """
        遍历节点
        :return:
        """
        cur = self.head
        while cur is not None:
            print(cur.item)
            cur = cur.next

    def isEmpty(self):
        """
        链表判空
        :return:
        """
        return self.head is None

    def length(self):
        """
        链表的长度
        :return:
        """
        count = 0  # 记录节点个数
        cur = self.head
        while cur is not None:
            count += 1
            cur = cur.next
        return count

    def insertNode(self, item, pos):
        """
        新节点插入pos位置处
        :param item:
        :param pos:
        :return:
        """
        node = Node(item)
        cur = self.head
        pre = None
        if pos == 0:
            self.head = node
            node.next = cur
            return
        for i in range(pos):
            pre = cur
            cur = cur.next

        pre.next = node
        node.next = cur

    def removeNode(self, item):
        """
        从链表删除item表示的节点
        :param item:
        :return:
        """
        cur = self.head
        pre = None
        if self.head.item is item:  # 删除第一个节点
            self.head = cur.next
            return
        while cur is not None:
            if cur.item is item:
                pre.next = cur.next
                return
            else:
                pre = cur
                cur = cur.next

    def append(self, item):
        """
        向链表尾部添加新的节点
        :param item:
        :return:
        """
        node = Node(item)
        if self.isEmpty():  # 判断是否为空,如果为空直接作为头节点
            self.head = node
        else:
            pre = None  # pre指向cur前面的一个节点
            cur = self.head
            while cur is not None:
                pre = cur
                cur = cur.next
            pre.next = node


link = Link()
link.addHead(1)
link.addHead(2)
link.addHead(3)
link.addHead(4)
link.addHead(5)
link.travel()
print(link.isEmpty())
print(link.length())
print("======" * 10)
link.append(6)
link.travel()
print("======" * 10)
link.insertNode('xxx', 0)
link.travel()
print("======" * 10)
link.removeNode('xxx')
link.travel()

异常处理

print('start')
try:
    1 / 0
except ZeroDivisionError as i:
    print(i)

print('end')
sex = int(input('please input a number:'))
try:
    if sex == 1:
        print('xx')
    elif sex == 0:
        print('yy')
    else:
        print('zz')
        raise ValueError('非法输入')
except ValueError:
    print('xx')
举报

相关推荐

0 条评论