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
  • 相关阅读:
    hdu 1042 N!
    hdu 1002 A + B Problem II
    c++大数模板
    hdu 1004 Let the Balloon Rise
    hdu 4027 Can you answer these queries?
    poj 2823 Sliding Window
    hdu 3074 Multiply game
    hdu 1394 Minimum Inversion Number
    hdu 5199 Gunner
    九度oj 1521 二叉树的镜像
  • 原文地址:https://www.cnblogs.com/perfey/p/9200741.html
Copyright © 2011-2022 走看看