• 面向对象的编程


    首先要清楚面向对象的几个重要的问题:

    1.什么是类

    2.什么是对象

    3.self是什么

    4.构造函数和析构函数

    5.私有和共有

    6.静态和动态

    7.特性

    8.特殊的__init__和__call__方法

    接口

      接口就是制定一种规则,当类继承继承接口的时候就是在制定的这种规则之上进行的定义。接口说白了就是把架构都设定好了,继承接口的类就就必须按照这个架构进行编写,函数的名字不能有所改变。

    抽象类加抽象方法就是接口。

     1 from abc import ABCMeta,abstractmethod
     2 
     3 class bar:
     4     __metaclass__ = ABCMeta
     5 
     6     @abstractmethod
     7     def foo1(self):
     8         pass
     9 
    10 class bin(bar):
    11 
    12     def foo(self):
    13         print 'xxxx'
    14         
    15 f = bin()
    16 f.foo()

    定义类并创建实例

      类通过class关键字进行定义。按照Python的编程习惯,类名以大写字母开头,紧接着是(object),表示该类是从哪个类基础下来的。创建实例使用 类名+(),类似函数调用的形式

      (例子)请练习定义Person类,并创建出两个实例,打印实例,再比较两个实例是否相等。        

        要打印实例,直接使用print语句;

        要比较两个实例是否相等,用==操作符。

    class Person(object):

        pass
    xiaoming = Person()
    xiaohong = Person()
    print xiaoming
    print xiaohong
    print xiaoming == xiaohong 
    创建实例的属性

    请创建包含两个 
    Person 类的实例的 list,并给两个实例的 name 赋值,然后按照 name 进行排序。

    初始化实例的属性

      在定义 Person 类时,可以为Person类添加一个特殊的__init__()方法,当创建实例时,__init__(){这里一定要注意是__init__,而不是__int__}方法被自动调用,我们就能在此为每个实例都统一加上以下属性:

      

    class Person(object):
        def __init__(self, name, gender, birth):
            self.name = name
            self.gender = gender
            self.birth = birth
    __init__() 方法的第一个参数必须是 self
      请定义Person类的__init__方法,除了接受 name、gender 和 birth 外,还可接受任意关键字参数,并把他们都作为属性赋值给实例。
    要定义关键字参数,使用 **kw
    除了可以直接使用self.name = 'xxx'设置一个属性外,还可以通过 setattr(self, 'name', 'xxx') 设置属性。

    class Person(object):

        def __init__(self, name, gender, birth, **kw):
            self.name = name
            self.gender = gender
            self.birth = birth
            for k, v in kw.iteritems():   #通过这种方式来给添加一个随机量
                setattr(self, k, v)
    xiaoming = Person('Xiao Ming', 'Male', '1990-1-1', job='Student')
    print xiaoming.name
    print xiaoming.job

    访问限制

      Python对属性权限的控制是通过属性名来实现的,如果一个属性由双下划线开头(__),该属性就无法被外部访问。

    •创建类属性

      绑定在一个实例上的属性不会影响其他实例,但是,类本身也是一个对象,如果在类上绑定一个属性,则所有实例都可以访问类的属性,并且,所有实例访问的类属性都是同一个!也就是说,实例属性每个实例各自拥有,互相独立,而类属性有且只有一份。

      class Person(object):

        address = 'Earth'
        def __init__(self, name):
            self.name = name

    因为类属性是直接绑定在类上的,所以,访问类属性不需要创建实例,就可以直接访问:

    print Person.address
    # => Eart

    对一个实例调用类的属性也是可以访问的,所有实例都可以访问到它所属的类的属性:

    p1 = Person('Bob')
    p2 = Person('Alice')
    print p1.address
    # => Earth
    print p2.address
    # => Earth

    由于Python是动态语言,类属性也是可以动态添加和修改的:

    Person.address = 'China'
    print p1.address
    # => 'China'
    print p2.address
    # => 'China
    因为类属性只有一份,所以,当Person类的address改变时,所有实例访问到的类属性都改变了。
      请给 Person 类添加一个类属性 count,每创建一个实例,count 属性就加 1,这样就可以统计出一共创建了多少个 Person 的实例。       


    类属性和实例属性名字冲突怎么办
      
    在实例变量上修改类属性 
         
    class Person(object):
        address = 'Earth'
        def __init__(self, name):
            self.name = name
    
    p1 = Person('Bob')
    p2 = Person('Alice')
    
    print 'Person.address = ' + Person.address
    
    p1.address = 'China'
    print 'p1.address = ' + p1.address
    
    print 'Person.address = ' + Person.address
    print 'p2.address = ' + p2.address

    结果如下:

    Person.address = Earth
    p1.address = China
    Person.address = Earth
    
    p2.address = Earth                                                 
    在设置了 p1.address = 'China' 后,p1访问 address 确实变成了 'China',但是,Person.address和p2.address仍然是'Earch'
    原因是 p1.address = 'China'并没有改变 Person 的 address,而是给 p1这个实例绑定了实例属性address ,对p1来说,它有一个实例属性address(值是'China'),而它所属的类Person也有一个类属性address

    访问 p1.address 优先查找实例属性,返回'China'
    可见,当实例属性和类属性重名时,实例属性优先级高,它将屏蔽掉对类属性的访问。
    定义实例的方法
       
     一个实例的私有属性就是以__开头的属性,无法被外部访问
      

      虽然私有属性无法从外部访问,但是,从类的内部是可以访问的。除了可以定义实例的属性外,还可以定义实例的方法。
      

      实例的方法就是在类中定义的函数,它的第一个参数永远是 self,指向调用该方法的实例本身,其他参数和一个普通函数是完全一样的:



    class Person(object):
    
        def __init__(self, name):
            self.__name = name
    
        def get_name(self):
            return self.__name
    
    

    调用实例方法必须在实例上调用:

    
    
    p1 = Person('Bob')
    print p1.get_name()  # self不需要显式传入
    # => Bob


    请给 Person的实例增加一个私有属性 __score,表示分数,再增加一个实例方法 get_grade(),能根据 __score 的值分别返回 A-优秀, B-及格, C-不及格三档。


    定义类的方法
      

    要在class中定义类方法,需要这么写:

    
    
    class Person(object):
        count = 0
        @classmethod
        def how_many(cls):
            return cls.count
        def __init__(self, name):
            self.name = name
            Person.count = Person.count + 1
    
    print Person.how_many()
    p1 = Person('Bob')
    print Person.how_many()
    
    

    通过标记一个 @classmethod,该方法将绑定到 Person 类上,而非类的实例。类方法的第一个参数将传入类本身,通常将参数名命名为 cls,上面的 cls.count 实际上相当于 Person.count

    腾飞前的蛰伏
  • 相关阅读:
    JAVA FTP 客户端 .
    附件上传byte2hex二行制转字符串优化方法
    JSTL的c:forEach标签(${status.index})
    jco 连接池
    FOWARD和response.sendRedirect()区别
    Windows BAT命令编写大全
    SQLServer 触发器详解
    区分ff/ie6/ie7/ie8,解决样式不兼容
    android在学习——程序的退出
    关于struts2 获取页面表单信息的个人做法
  • 原文地址:https://www.cnblogs.com/xiaoli2018/p/4354816.html
Copyright © 2020-2023  润新知