python-面向对象


# --思考,理解--
# 世界万物皆可分类。
# 世界万物皆为对象。
# 只要是对象,必属于某一个分类。
# 只要是对象,必有自己的属性。

# 三大特性。
# 封装 一个类中的属性或者方法,对于外部调用时是透明的。
# 继承 一个类可以派生出子类,父类中的属性方法自动被子类继承。
# 多态 一个接口,多种实现。例如:厂长发出工作指令,客服部开始打电话工作,装箱工人开始装箱工作,装车工人开始装车工作...一个工作指令,不同部门开始不同的工作。


#   代码实现理解。
#   这里定义了一个人类的模板。
class person:

    def __init__(self,name,sex):
        self.name = name
        self.sex = sex

    def introduce(self):
        print('你好,我叫',self.name,'性别是',self.sex)

    def sleep(self):
        print(self.name,'睡觉了...')

    def eat(self):
        print(self.name,'吃饭了....')

    def buy(self):
        print(self.name,'买了东西...')


#   上帝按照人类模板创造了三个人类
p1 = person('赵一','')
p2 = person('钱二','')
p3 = person('孙三','')

#   创造出的人类同时自我介绍之后,分别干了不同的事。
p1.introduce()
p1.eat()
p2.introduce()
p2.buy()
p3.introduce()
p3.sleep()

#   由此可见,面向对象的优点:1.类的功能属性一目了然。2.代码复用性高。


# 【详细理解】

# 我们再看看类,对象在内存中是怎么工作的?
# class 在python中是定义一个类的关键字,后面紧跟的是类的名字。所以 class person: 定义了一个名为person的class。
# 重点:类未实例化时,是已经存在内存中的。但是不能做任何操作。


class person:

    boby = '身体' #类变量,不实例化就能调用。

    def __init__(self,name):
        print('self',self)
        self.name = name #实例变量,实例化之后才能调用

    def introduce(self):
        print('introduce_self',self)
        print('你好,我是',self.name)


#   未实例的class,已经存在于内存中
print(person)
#   <class '__main__.person'>


#   实例后的class,称为对象。
#   由例子可知:实例化时,把自己实例化的内存地址传入了对象内,对象中调用其实是实例化时的内存地址引用。

print(person.boby)
person.boby = '张三的身体'
print(person.boby)
p1 = person('李三')
print(p1)
p1.introduce()
# 身体
# 张三的身体
# self <__main__.person object at 0x0000000000B73B00>
# <__main__.person object at 0x0000000000B73B00>
# introduce_self <__main__.person object at 0x0000000000B73B00>

print(person.boby)
p2 = person('张四')
print(p2)
p2.introduce()
# 张三的身体
# self <__main__.person object at 0x0000000000B73BE0>
# <__main__.person object at 0x0000000000B73BE0>
# introduce_self <__main__.person object at 0x0000000000B73BE0>
# 你好,我是 张四

#   现在张四觉得自己的名字不好听,想改名字。还想多加一个年龄的东西。
p2.name = '张五'
p2.age = 18
p2.introduce()
print(p2.age)
# introduce_self <__main__.person object at 0x0000000000B73BE0>
# 你好,我是 张五
# 18

# boby = '身体' 是类的变量,整一个类共享。
# self 即是类实例化的内存空间地址。
# self.name = 类实例化的变量,作用是其类的本身。
# def __init__(self):   init是类中python对象中自带的一个特殊的方法,叫做构造方法,实例化类时,第一个执行的就是init方法,也称做类的初始化工作。
# def introduce(self):  是自己自定义的一个普通方法。

# 私有方法,私有属性

class person:
    def __init__(self,name,deposit):
        self.name = name
        self.__deposit = deposit # 私有属性,两个下划线定义私有属性,只能由内部使用。

    def introduce(self):
        print('你好,我是',self.name)


    def buy(self,goodprice):
        print(self.name,'的存款为',self.__deposit)
        self.__layout(goodprice)
        print(self.name,'购买价格为{price}的商品,现在存款为{deposit}'.format(price=goodprice,deposit=self.__deposit))

    # 私有方法,存款的使用只能内部使用。
    def __layout(self,goodprice):
        self.__deposit -= goodprice

    #   析构方法,对象销毁时会自动调用次方法,与init是一对。与人的出生和死亡对应。
    def __del__(self):

        print(self.name,'安享天年了...')



#print(p1.__deposit)  #AttributeError: 'person' object has no attribute '__deposit'
#p1.__layout(2000) #AttributeError: 'person' object has no attribute '__layout'
p1 = person('张三',20000)
p1.introduce()
p1.buy(988)
# 你好,我是 张三
# 张三 的存款为 20000
# 张三 购买价格为988的商品,现在存款为19012
# 张三 安享天年了...

# 继承

#   两种类,继承中的两种写法。
# 经典类,py2
class person:
    pass

#  新式类,py3
class good(object):
    pass
# 继承的特点和要点。
class person:
    def __init__(self,name,age):
        print('person的self内存地址',self)
        self.name = name
        self.age = age

    def sleep(self):
        print(self.name,'睡觉了...')

    def eat(self):
        print(self.name,'吃饭了...')

    def talk(self):
        print(self.name,'说话了...')

    def __creator(self):
        print('上帝')

    def __del__(self):
        print(self.name,'安享天年了...')


# 括号中说明:man类继承person类的所有的属性和方法。 class man(person): # 继承父类的构造方法,然后自定义自己的构造方法。 def __init__(self,name,age,life): super(man,self).__init__(name,age) # 先调用父类方法。推荐。 # person.__init__(self, name, age) #先调用父类的另一种方式。功能同上。 self.life = life def daiba(self): print('man的self内存地址',self) # 继承中,子类对象使用的内存地址是父类的对象的内存地址。 print(self.name,'带把的生命是',self.life) def talk(self): print(self.name,'man重写了person','说话了') m1 = man('张三',23,80) m1.daiba() m1.sleep() # 继承了person的睡觉。 m1.talk() #m1.__creator() 但是不能继承父类中的私有属性和私有方法 #AttributeError: 'man' object has no attribute '__wife' # person的self内存地址 <__main__.man object at 0x0000000000709A20> # man的self内存地址 <__main__.man object at 0x0000000000709A20> # 张三 带把的生命是 80 # 张三 睡觉了... # 张三 man重写了person 说话了 # 张三 安享天年了...
# 多继承的顺序
class person(object):
    def __init__(self,name):
        self.name = name

    def eat(self):
        print(self.name,'吃饭了..')

class Man(person):
    def man(self):
        print(self.name,'男性...')
    def sleep(self):
        print('man睡觉')

class Woman(person):
    def birth(self):
        print(self.name,'生孩子了...')
    def sleep(self):
        print('woman睡觉')
    def eat(self):
        print('woman吃饭了。。。')

# 多继承方式如下
class Children(Man,Woman):
    def talk(self):
        print('我是孩纸...')

# 问题1:继承多个父类,父类中有相同的方法和属性,继承顺序如何判定?
# 答:继承顺序从左到右。如:Children(Man,Woman):  先Man后Woman   例子:c1.sleep()

# 问题2:继承多个父类,而且其中一个父类还继承了其他父类,继承顺序是如何判定?
# 答:继承顺序还是从左往右,再往上寻找。

# 经典类时按深度优先进行查找,新式类时按广度优先进行查找。py2默认是按深度,py3默认是按广度。

c1 = Children('张小小')
c1.man()
c1.sleep()
c1.eat()
# 张小小 男性...
# man睡觉
# woman吃饭了。。。
# 多继承的self问题?

# 思考,以下代码调用的事哪一个eat()?
# 答,Man的eat().因为man 已经继承了person的get_eat()。
# 经典类时按深度优先进行查找,新式类时按广度优先进行查找。py2默认是按深度,py3默认是按广度。
# 而且由此可见,self 永远是指向当前实例化的对象,和继承没有半毛钱关系。
class person(object):
    def get_eat(self):
        self.eat()

    def eat(self):
        print('person:',self)

class Man(person):
    def eat(self):
        print('Man:',self)

class Son(Man,person):
    pass

s1 = Son()
print('s1:',s1)
s1.get_eat()
# s1: <__main__.Son object at 0x0000000001049908>
# Man: <__main__.Son object at 0x0000000001049908>

 

# 构造方法,析构方法,静态方法,类方法,普通方法。

class food(object):

    name = '类变量'
    def __init__(self,name,color):
        """
        构造方法,实例化类时便开始执行。
        :param name:
        :param color:
        """
        print('这是构造方法....')
        self.name = name

    def grow(self):
        print('这是一个普通方法....')

    @classmethod
    def set(cls):
        """
        只能访问类变量。
        :return:
        """
        print('这是一个类方法....',cls.name)
        cls.get()

    @staticmethod
    def get():
        """
        实际上和类没有了关系,只是放在这个类中。
        由不添加self可以看出
        :return:
        """
        print('这是一个静态方法....')

    @property
    def lists(self):
        """把一个方法变成属"""
        print('这是一个属性方法....')

    def __del__(self):
        """
        对象销毁时,自动执行该方法。
        :return:
        """
        print('这是一个析构方法...')

food.get()
f1 = food('苹果','red')
f1.set()
f1.lists
f1.grow()
# 这是一个静态方法....
# 这是构造方法....
# 这是一个类方法.... 类变量
# 这是一个静态方法....
# 这是一个普通方法....
# 这是一个析构方法...
额外的理解:



# 类的特殊成员方法
# __doc__ __module__ __class__ __call__ __dict__ __str__
class food(object):
    """这是一个关于食物的类"""
    pass

    def __call__(self, *args, **kwargs):
        print('这是个call方法')

    def __str__(self):
        # 设置类的别名
        return 'food类'

print(food.__doc__) # 说明类的描述信息。

print(food.__module__) # 说明从哪个模块而来

print(food.__class__) # 说明从哪个类而来

f1 = food()
f1() # __call__ 类实例化之后,还能实例化调用。

print(food.__dict__) # 查看类或者对象的所有的成员。

print(f1.__dict__)  # 查看实例化后的对象的的成员属性。

print(f1) # 查看类的别名。

 

#   类的 __getitem__  __setitem__ __delitem__

class food(object):

    def __init__(self):
        self.data = {}

    def __getitem__(self, item):
        print('getitem',item)
        return self.data.get(item)

    def __setitem__(self, key, value):
        print('setitem',key,value)
        self.data[key]=value

    def __delitem__(self, key):
        print('delitem',key)

# 设置类的变量可以更加简单的编辑。
#   看如下的例子

f1 = food()
f1['name'] = 'Dog'

name = f1['name']
print(name)

del f1['name']

# setitem name Dog
# getitem name
# Dog
# delitem name
# 类实例化之前的定制。
class food(object):

    def __init__(self):
        self.name = 'ddddddd'
        print('init......')

    def __new__(cls, *args, **kwargs):
        """
        重写实例化开始的操作.
        :param args:
        :param kwargs:
        :return:
        """
        print('实例化.....')
        return object.__new__(cls) # 继承object的new方法,继承父类的实例化方法。

f1 =food()
print(f1.name)
# 实例化.....
# init......
# ddddddd

 练习代码:

#   成员属性,分页小程序。
class pages:
    def __init__(self,current_page):
        try:
            p = int(current_page)
        except Exception as e:
            p = 1
        self.curpage = p
        self.totalcount = totalcount


    @property
    def startpage(self):
        val = (self.curpage-1) * 10
        return val

    @property
    def endpage(self):
        val = self.curpage * 10
        return val
    
li = []
for i in range(100):
    li.append(i)

while True:
    inp =  input('请输入你想查看的页面数:')
    obj  =  pages(inp)
    print(li[obj.startpage:obj.endpage])
View Code

 

 

 

 





posted @ 2018-05-16 14:20  豆腐不怕卤水的经历  阅读(298)  评论(0编辑  收藏  举报