zoukankan      html  css  js  c++  java
  • Python 面向对象编程

     1.类和实例

    对于Python,声明与定义类没什么区别,同时进行。定义(类体)紧跟在声明(含class的头行)和可选的文档字符串后面

     1 #!/usr/bin/python3
     2 
     3 class Student(object):
     4 #表示该类从哪个类继承下来的,如没有合适的继承类,就是用object类
     5 #这是所有类最终都会继承的类
     6     def __init__(self,name,score):
     7         self.name = name
     8         self.score = score
     9     def print_score(self):
    10         print('%s:%s' % (self.name, self.score))
    11 
    12 b = Student('Chb', 100)   #创建实例
    13 print(b.name)
    14 print(b.score)
    15 print(b.print_score())

    如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有在类的内部可以访问,外部不能访问

    类有一个名为 __init__() 的特殊方法(构造方法),该方法在类实例化时会自动调用,重写__init__不会自动调用基类的__init__,如想调用基类的__init__():

    1 class C(P):
    2     def __init__(self):
    3         P.__init__(self)
    4         print("....")

    任何类都有的特殊属性():

    1 A.__name__    #类A的名字 特殊属性都是两个下划线开头
    2 A.__doc__    #类A的文档字符串
    3 A.__bases__    #类A的所有父类构成的元组
    4 A.__dict__    #类A的属性
    5 A.__module__#类A定义所在模块
    6 A.__class__    #实例A对于的类
    View Code

    类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称, 按照惯例它的名称是 self

    self代表类的实例,而非类,表示创建的实例本身

    实例绑定的数据属性属于实例对象,类数据属性(即静态数据类型)是属于类的

    1 class C(object):
    2     foo = 100
    3 
    4 print(C.foo)    #100
    5 B = C()
    6 B.foo = C.foo+100
    7 print(B.foo)    #200
    8 print(C.foo)    #100

    2.获取对象信息

    当我们拿到一个对象的引用时,如何知道这个对象是什么类型、有哪些方法呢?

    使用type()

    返回对应的class类型

    使用isinstance(obj1,obj2)

    布尔函数判断一个对象是否是另一个给定类的实例

    使用issubclass(sub,sup)

    布尔函数判断一个类是另一个类的子类或子孙类

    使用dir()  

    如果要获得一个对象的所有属性和方法,可以使用dir()函数,它返回一个包含字符串的list

    __slots__  限制实例的属性

    在Python中,定义一个class类并创建了一个class的实例后,可以给该实例绑定任何属性和方法,这是动态语言的灵活性

    但是,给一个实例绑定的方法,对另一个实例是不起作用的

    如果我们想要限制实例的属性怎么办?比如,只允许对Student实例添加nameage属性。

    为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性

    由于'score'没有被放到__slots__中,所以不能绑定score属性,试图绑定score将得到AttributeError的错误。

    使用__slots__要注意,__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的

    @property

    @property广泛应用在类的定义中,可以让调用者写出简短的代码,同时保证对参数进行必要的检查。把一个方法变成属性调用

     1 #!/usr/bin/python3
     2 
     3 class Student(object):
     4     @property
     5     def score(self):
     6         return self._score
     7     @score.setter
     8     def score(self, value):
     9         if not isinstance(value, int):
    10             raise ValueError('分数必须是整数')
    11         if value<0 or value>100:
    12             raise ValueError('分数必需在0~100之间')
    13         self._score = value
    14 
    15 s = Student()
    16 s.score = 60
    17 print(s.score)
    18 print('------------------------------')
    19 s.score = 999
    20 print(s.score)

    3.多重继承

    给一个类增加多个功能,多继承时,若是基类中有相同的方法名,而在子类使用时未指定,Python从左至右搜索

    class Dog(A, B, C):
        pass

    4.定制类

    非常方便生成特定的类

    __str__   

    打印自定义的实例

     1 #!/usr/bin/python3
     2 
     3 class Student(object):
     4     def __init__(self, name):
     5         self.name = name
     6     def __str__(self):
     7         return 'Student object (name:%s)' % self.name
     8     __repe__ = __str__
     9 
    10 s = Student('Chb')
    11 print(s)

     __iter__

    如果一个类想被用于for ... in循环,类似list或tuple那样,就必须实现一个__iter__()方法,该方法返回一个迭代对象,然后,Python的for循环就会不断调用该迭代对象的__next__()方法拿到循环的下一个值,直到遇到StopIteration错误时退出循环。

     1 #!/usr/bin/python3
     2 
     3 class Fib(object):
     4     def __init__(self):
     5         self.a, self.b = 1,1
     6     def __iter__(self):
     7         return self  #实例本身就是迭代对象,故返自己
     8     def __next__(self):
     9         self.a, self.b = self.b, self.a+self.b
    10         if self.a > 1000:  #退出循环条件
    11             raise StopIteration()
    12         return self.a
    13         
    14 for n in Fib():
    15     print(n)

     __getitem__

    使自己定义的类型和list、dict没什么区别,如可以按索引取值、切片

     1 #!/usr/bin/python3
     2 
     3 class Fib(object):
     4     def __getitem__(self, n):
     5         if isinstance(n, int):  #n是索引的情况
     6             a, b = 1, 1
     7             for x in range(n):
     8                 a, b = b, a+b
     9             return a
    10         if isinstance(n, slice):  #n是切片的情况
    11             start = n.start
    12             stop = n.stop
    13             if start is None:  #如果开头没赋值 L[::] 则默认开始下标为0
    14                 start = 0
    15             a, b = 1, 1
    16             L = []
    17             for x in range(stop):
    18                 if x >= start:
    19                     L.append(a)
    20                 a, b = b, a+b
    21             return L
    22         
    23 f = Fib()
    24 print(f[10])
    25 print(f[0:5])

    __getattr__

    正常情况下,当我们调用类的方法或属性时,如果不存在,就会报错。

    要避免这个错误,可以写一个__getattr__()方法,动态返回一个属性。

     1 #!/usr/bin/python3
     2 
     3 class Student(object):
     4     def __init__(self):
     5         self.name = 'aaa'
     6     def __getattr__(self, attr):
     7         if attr == 'score':
     8             return 60
     9             
    10 s = Student()
    11 print(s.name)
    12 print(s.score)

    当调用不存在的属性时,比如score,Python解释器会试图调用__getattr__(self, 'score')来尝试获得属性,这样,我们就有机会返回score的值

    __call__

    直接对实例进行调用

     1 #!/usr/bin/python3
     2 
     3 class Student(object):
     4     def __init__(self, name):
     5         self.name = name
     6     def __call__(self):
     7         print('My name is %s' % self.name)
     8             
     9 s = Student('chb')
    10 print(s())

    6.实例方法、类方法、静态方法

    实例方法:类实例化后才能调用,参数的值不能调用类属性

    类方法:只能调用类属性,类和实例都能调用它

    1 @classmethod
    2 def classget(cls):
    3     print(cls.x)

    静态方法:类对象和实例都可以调用的静态方法

    1 @staticmethod
    2 def add(a,b):
    3     return a+b
     1 class A():
     2     
     3     x = 100
     4     @classmethod
     5     def classget(A):
     6         print(A.x)
     7 
     8     @staticmethod
     9     def add(a,b):
    10         return a+b
    11         
    12 if __name__=='__main__':
    13     a = A()
    14     A.classget()    #100
    15     a.classget()    #100
    16     sum1 = a.add(2,3)
    17     sum2 = A.add(2,5)
    18     print(sum1,sum2)    #5    7
    View Code
  • 相关阅读:
    继承关系中子类使用@Data注解问题
    Professional, Entreprise, Architect版本的区别
    Delphi中ARC内存管理的方向
    技术的止境(客户价值第一,快速实现第二,边做边学,迅速成为牛人。紧贴客户的需求去做技术,立于不败之地。追求的目标:把一项产品去做好,用产品去养活自己和家人)good
    C++ 函数模板与类模板(使用 Qt 开发编译环境)
    C++进阶之虚函数表
    Net反编译软件
    python虚拟环境--virtualenv和virtualenvwrapper
    Windows同时安装python3和python2
    python的pip源在windows和linux修改
  • 原文地址:https://www.cnblogs.com/bfcs/p/10744665.html
Copyright © 2011-2022 走看看