zoukankan      html  css  js  c++  java
  • python 面向对象编程 类和实例

    class Student(object):  #class后面紧接着是类名,即Student,类名通常是大写开头的单词,紧接着是(object),表示该类是从哪个类继承下来的.通常,如果没有合适的继承类,就使用object类,这是所有类最终都会继承的类。
        def __init__(self,name,score):      #通过定义一个特殊的__init__方法,在创建实例的时候,就把类的name,score等属性绑上去,__init__方法的第一个参数永远是self,表示创建的实例本身,因此,在__init__方法内部,就可以把各种属性绑定到self,因为self就指向创建的实例本身,除了self外,其他参数和函数的参数一致,仍然可以用默认参数、可变参数、关键字参数和命名关键字参数。
            self.name = name
            self.score = score
        def print_score(self):      #在Student类的内部定义访问数据的函数,这样,就把“数据”给封装起来了。这些封装数据的函数是和Student类本身是关联起来的,我们称之为类的方法,要定义一个方法,除了第一个参数是self外,其他和普通函数一样。要调用一个方法,只需要在实例变量上直接调用,除了self不用传递,其他参数正常传入.
            print("%s:%s" % (self.name,self.score))
        def get_grade(self):        #封装的另一个好处是可以给Student类增加新的方法,比如get_grade,同样的,get_grade方法可以直接在实例变量上调用,不需要知道内部实现细节
            if self.score >= 90:
                return "A"
            elif self.score >= 60:
                return "B"
            else:
                return "C"
    bar = Student("Bart Simpson",59)
    bar.print_score()
    ret = bar.get_grade()
    print(ret)
    lisa = Student("Lisa Simpson",87)
    lisa.age = 18
    print(dir(lisa))    #使用dir()来查看类(或者是变量)可以使用的方法,可以看到Lisa实例比bar实例多了个age方法,这是因为我们的lisa.age = 18语句给lisa添加了新属性age.和静态语言不同,Python允许对实例变量绑定任何数据,也就是说,对于两个实例变量,虽然它们都是同一个类的不同实例,但拥有的变量名称都可能不同.
    #['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'get_grade', 'name', 'print_score', 'score']
    print(dir(bar))
    #['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'get_grade', 'name', 'print_score', 'score']
    #********************************************访问限制**********************************
    #在Python中,变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量
    #有时候会看到单下划线开头的变量,比如_name,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”
    #双下划线开头的实例变量一般是不能直接从外部访问的,但是也不是一定不能从外部访问呢。不能直接访问__name是因为Python解释器对外把__name变量改成了_Student__name,所以,仍然可以通过_Student__name来访问__name变量,但是强烈建议你不要这么干,因为不同版本的Python解释器可能会把__name改成不同的变量名
    class Student(object):
        def __init__(self,name,score):
            self.__name = name
            self.__score = score
        def print_score(self):
            print("%s:%s" % (self.__name,self.__score))
        def set_score(self, score):     #通过内部方法来在类内部修改__score   #在方法中,可以对参数做检查,避免传入无效的参数:
            if 0 <= score <= 100:
                self.__score = score
            else:
                raise ValueError('bad score')
    bart = Student("Bart simpson",59)
    bart.print_score()
    #Bart simpson:59
    bart.set_score(89)
    bart.print_score()
    #Bart simpson:89
    #*************************************继承和多态************************************
    class Animal(object):
        def run(self):
            print('Animal is running...')
    
    class Dog(Animal):
        pass
    dog = Dog()     #把Dog这个类给出一个实例dog,注意Dog后面的括号
    dog.run()       #子类Dog获得了父类Animal的全部功能。由于Animial实现了run()方法,因此,Dog作为它的子类,什么事也没干,就自动拥有了run()方法
    #Animal is running...
    
    class Dog(Animal):
        def run(self):
            print("Dog is running")
    Dog().run()     # ==>   dog = Dog()   dog.run()    Dog()代表的就是实例,这里只是没有把这个实例赋值给一个具体的变量
    #Dog is running             当子类和父类都存在相同的run()方法时,我们说,子类的run()覆盖了父类的run(),在代码运行的时候,总是会调用子类的run()。这样,我们就获得了继承的另一个好处:多态
    
    #****数据类型
    #当我们定义一个class的时候,我们实际上就定义了一种数据类型。我们定义的数据类型和Python自带的数据类型,比如str、list、dict没什么两样:
    a = list() # a是list类型
    b = Animal() # b是Animal类型
    c = Dog() # c是Dog类型
    #判断一个变量是否是某个类型可以用isinstance()判断,之前也说过了
    #在继承关系中,如果一个实例的数据类型是某个子类,那它的数据类型也可以被看做是父类,在上面可以这样说,c是Dog类型,c也是Animal类型
    #**********************************获取对象信息********************************
    print(type("abc"))
    #<class 'str'>
    print(isinstance("abc",str))
    #True
    print(dir("abc"))   #获取一个对象所有属性和方法
    #['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
    #操作对象属性 getattr()、setattr()以及hasattr()
    class MyObject(object):
        def __init__(self):
            self.x = 9
        def power(self):
            return self.x * self.x
    
    obj = MyObject()
    
    
    print(hasattr(obj, 'x'))    # 有属性'x'吗?
    #True
    print(obj.x)
    #9
    print(hasattr(obj, 'y'))    # 有属性'y'吗?
    #False
    setattr(obj, 'y', 19) # 设置一个属性'y'
    print(hasattr(obj, 'y')) # 有属性'y'吗?
    #True
    print(getattr(obj, 'y')) # 获取属性'y'
    #19
    print(obj.y) # 获取属性'y'
    #19
    #************************实例属性和类属性***************
    #之前讲的是给实例添加属性,抽象的类也可以添加
    class Student(object):
        name = "Student"
        def __init__(self,name):
            self.name = name
    s = Student("Bob")      #创建实例
    s.score = 90        #实例 s 添加score属性
    print(s.name)
    #Bob
    print(Student.name) #实例的 name 属性
    #Student
    del s.name      #删除实例 s 的name属性
    print(s.name)   #当实例 s 没有找到自己name属性时,引用的是类的name属性,这个特性类似于继承 子类和父类的关系
    #Student        #所以,不要对实例属性和类属性使用相同的名字,因为相同名称的实例属性将屏蔽掉类属性,但是当你删除实例属性后,再使用相同的名称,访问到的将是类属性.
    
    #为了统计学生人数,可以给Student类增加一个类属性,每创建一个实例,该属性自动增加
    class Student(object):
        count = 0
        def __init__(self,name):    #一个类,如果被实例化,就会默认执行一次init()函数,所以在__init__函数中进行count累加操作
            self.name = name
            Student.count += 1
    print(Student.count)
    # 0
    bart = Student("bart")
    print(Student.count)
    # 1
    lisa = Student("lisa")
    print(Student.count)
    # 2

     #  在类的方法中再定义函数,然后实例类对象,引用这个方法

     1 class A():
     2     def func(self):
     3         def func1():
     4             print('123')
     5         def func2():
     6             print('456')
     7         self.func1 = func1
     8         self.func2 = func2
     9 a = A()
    10 a.func()
    11 a.func1()
    12 a.func2()
    13 # 123
    14 # 456
  • 相关阅读:
    IOS开发--网络篇-->GCD(Grand Central Dispatch)的详解
    drf viewset
    12.6 drf 结构化组建
    12.5
    12.4
    12.3
    12.2
    12.1 angular vue react web前端三大主流框架的对比
    11.30
    11.28 过滤器的相关操作
  • 原文地址:https://www.cnblogs.com/perfey/p/9200741.html
Copyright © 2011-2022 走看看