传智播客旗下高端IT在线教育平台 线下学院

返回顶部 返回列表
楼主: 18380582253

[Python专区] Chenke 的Python体验班学习笔记

[复制链接]

3

主题

15

帖子

69

积分

注册会员

Chenke

Rank: 2

积分
69
 楼主| Chenke 发表于 2017-8-4 17:56:14
2017/8/4 学习笔记

1-16 隐藏对象属性
class Dog:
        def set_age(self,new_age):
                #对输入的数据进行合理性判断
                if new_age>0 and new_age<=100:
                        self.age = new_age
                else:
                        self_age = 0
        
        def get_age(self):
                return self.age

dog = Dog()
#想设置dog的年龄
#给对象添加属性
'''
dog.age = 10
dog.name = "小白"
print(dog.age)
dog.age = -10
print(dog.age)
'''
#如果不小心把age定义成了负值,还是正常输出。这种方式有一定的风险存在,可能值不在合理范围内

#定义一种方法来实现
#属性的设置建议都用方法来实现
dog.set_age(10)        #设置
age = dog.get_age()        #获取
print(age)
#dog.get_name()


class Person:
        def __init__(self,new_name,new_age):
                self.name = new_name
                self.age = new_age

        def setAge(self,new_age):
                if new_age>0 and new_age<= 100:
                        self.age = new_age

laowang = Person("老王",30)
laowang.age += 1
#对象名.属性 这种方式来修改属性很危险,慎用
print(laowang.age)

#定义一个方法来修改属性
laowang.setAge(80)
print(laowang.age)

#一般对于外面要用的属性来说,可以在类里面定义两个方法:一个set值,一个get值

#但是通过方法来设置和获取属性,在外面依然可以访问到属性值,并进行修改,这也是不安全的。
#如上面依然可以访问 laowang.age



1-17 私有属性
如果有一个对象,当需要对其进行修改属性时,有2种方法

对象名.属性名 = 数据 ---->直接修改
对象名.方法名() ---->间接修改
为了更好的保存属性安全,即不能随意修改,一般的处理方式为

将属性定义为私有属性
添加一个可以调用的方法,供调用

#做以下修改:
class Person:
        def __init__(self,new_name,new_age):
                #只要属性名前面有两个下划线__,那么就表示私有的属性
                #所谓的私有,即在程序中,不能在外部使用 对象名.属性名 获取
                #
                #原来没有添加__的属性,默认是 共有 的

                self.__name = new_name
                self.__age = new_age

        def setAge(self,new_age):
                if new_age>0 and new_age<= 100:
                        self.__age = new_age

        def getAge(self):
                return self.__age

        def test(self):
                print(self.__age)

laowang = Person("老王",30)
#laowang.age += 1

#laowang.setAge(80)
#print(laowang.__age)
#AttributeError: 'Person' object has no attribute '__age'
#现在已经不能在外面访问属性 __age 了
#属性前添加下划线之后就变成了私有属性了
#laowang.__age = 18
#laowang.test()
#结果:30
#即laowang.__age = 18,添加了一个__age属性,但是并没有对对象里面的__age进行修改
#laowang.__age = 18 是动态添加的一个属性,并没有影响到对象里面的值
#在属性成为私有属性之后,可以通过两个方法,跟外面进行联系

laowang.setAge(31)
age = laowang.getAge()
print(age)

1-18 私有方法
属性加下划线变成私有属性,方法加下划线就应该是私有方法。

做以下修改:
class Person:
        def __init__(self,new_name,new_age):
                #只要属性名前面有两个下划线__,那么就表示私有的属性
                #所谓的私有,即在程序中,不能在外部使用 对象名.属性名 获取
                #
                #原来没有添加__的属性,默认是 共有 的

                self.__name = new_name
                self.__age = new_age

        def setAge(self,new_age):
                if new_age>0 and new_age<= 100:
                        self.__age = new_age

        def getAge(self):
                return self.__age

        #私有方法,外面就不能使用了,隐藏的
        def __test(self):
                print("-----test1-----")

        #通过一个公开的方法,去调用了这个隐藏的私有方法
        #可以在公开的方法中进行判断,就可以对私有方法的使用,进行限制
        #没有__的公开的方法,就叫接口
        def test2(self):
                self.__test()
                print("-----test2-----")
        #实际开发中,协作者间需要一个文档来进行沟通

laowang = Person("老王",30)
laowang.setAge(31)
age = laowang.getAge()
print(age)

#会报错
#laowang.__test()

laowang.test2()

1-19 __del__() 方法
class Dog:
        # __del__这个方法在该对象被删除之后,自动执行
        def __del__(self):
                print("...........")

dog1 = Dog()
dog2 = dog1        #没有创建额外的对象,只是创建了新建了一个引用

del dog1 #del也可以删除一个对象,但是这儿只是删除了dog1这个引用,对象其实并没有被删除,此时还有dog2指向对象。
print("===========")
结果:
===========
...........
如果改成:
del dog1
del dog2
结果:
...........
===========
在程序里面对一个对象,有一个引用计数(垃圾回收机制)
为什么只删除dog1,最后还是会打印........?
程序运行完后,会退出,运行期间占用的内存,都要释放。所以会打印。
查看引用计数
import sys
sys.getrefcount(a)
#测量一个对象的引用计数方式

class T:
        pass

t = T
sys.getrefcount(t)
2#比实际的个数多1 ,因为将t当作参数传入后,还加了函数里面的那个对象。
tt = t
sys.sys.getrefcount(t)
3
del tt
del t
sys.sys.getrefcount(t)
#报错,t已经没了

1-20 继承
父类(基类)、子类(派生类)
                        
父类<--子类1
        <--子类2

子类使用父类的功能

class Animal:
        def eat(self):
                print("吃")
        def drink(self):
                print("喝")
        def sleep(self):
                print("睡")
        def run(self):
                print("跑")
#狗需要的一些功能,在Animal中全部有
#定义一个狗类,直接继承Animal的功能,不需要复制过来
#将Animal当成父类
class Dog(Animal):
        def bark(self):
                print("汪汪叫")

class Cat(Animal):
        def catch(self):
                print("抓老鼠")
#a = Animal()
#a.run()
a = Dog()
a.drink()
1-21 继承扩展
class Xiaotq(Dog):
        def fly(self):
                print("飞")

#a = Animal()
#a.run()
a = Xiaotq()
a.fly()
a.bark() #父类Dog的功能
a.eat()        #父类的父类Animal的功能

1-22 重写
需要对父类中的功能进行一些修改,这时候只需要在子类中重写该功能。
class Xiaotq(Dog):
        def fly(self):
                print("飞")
        def bark(self):
                print("狂叫")
        #这时候再去调用父类的功能
        #第一种
        #Dog.bark(self)#要传self
        #第二种
                super().bark()

a = Xiaotq()
a.bark() #父类Dog的功能               
#首先看子类中有没有这个功能,有的话直接用子类中的功能,没有的话就调用父类中的功能。
#重写的方法,只会调用的重写之后的,不会调用父类的。
#当父类的方法也是重写方法的一部分的时候,就需要在重写的方法内部调用父类的方法(有自己的功能,也有父类的功能)
#第一种方法:直接  父类名.方法(self)  一定要加self
#第二种方法:super().bark()        调用了父类中的方法

1-23 私有方法和私有属性在继承中的表现
class A:
        def __init__(self):
                self.num =100
                self.__num2=200

        def test1(self):
                print("test1")

        def __test2(self):
                print("test2")

        def test3(self):
                self.__test2()
                print(self.__num2)

class B(A):
        def test4(self):
                self.__test2()
                print(self.__num2)
        #会报错,如果调用的是继承的父类的共有方法,可以在这个共有方法中访问父类中的私有属性和私有方法
        #但是如果在子类中实现了一个共有方法, 那么这个方法是不能够调用继承的父类中的私有方法和私有属性

b = B()
b.test1()
#b.__test2()
#报错,说明私有方法不被继承
print(b.num)
#print(b.__num2)
#报错,私有属性也不会被继承
b.test3()        #可以通过共有方法去访问私有属性和方法
b.test4()

1-24 多继承
一个子类继承多个父类
class Base(object):        
#object是默认的,这是所有类的最顶层的类,写不写都会继承

#写上object,叫做新式类,python是默认继承object的,都是新式类
#不写object,叫做经典类。python3都是新式类
        def test(self):
                print("Base")

class A(Base):
        def test1(self):
                print("test1")
class B(Base):
        def test2(self):
                print("test2")

#小括号里面多个类,就叫多继承
class C(A,B):
        pass

c= C()
c.test1()
c.test2()
c.test()
#都可以调用
注意:
class Base(object):        
#object是默认的,这是所有类的最顶层的类,写不写都会继承

#写上object,叫做新式类,python是默认继承object的,都是新式类
#不写object,叫做经典类。python3都是新式类
        def test(self):
                print("Base")

class A(Base):
        def test(self):
                print("A")
class B(Base):
        def test(self):
                print("B")

#小括号里面多个类,就叫多继承
class C(A,B):
        pass
        #def test(self):
        #        print("C")

c= C()
c.test()
#因为C里面有test(),所以直接用C()里面的方法
#如果C里面没有test()方法的话,会调用A()

print(C.__mro__)
#搜索方法的优先顺序,自动遍历
#(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.Base'>, <class 'object'>)
#这个决定了调用一个方法的时候,搜索的循序,如果在某个类中找到了方法,那么就停止搜索。
#C3算法,决定了mro的输出,即决定了搜索顺序。
#尽可能保证类之间没有相同的方法

1-25 多态
定义时的类型和运行时的类型不一样,此时就成为多态。
class Dog(object):
        def print_self(self):
                print("我是。。。。。。")

class Xiaotq(Dog):
        def print_self(self):
                print("hello everbody")

def introduce(temp):
        temp.print_self()
#多态,定义的时候仅仅是知道调用了一个方法,但是不知道具体是谁的方法。只有在执行的之后,才知道具体是哪个对象的方法。


dog1 = Dog()
dog2 = Xiaotq()
introduce(dog1)
introduce(dog2)

#python面向对象的三个要素:封装(对象)、继承、多态


1-26 类属性、实例属性
class Tool(object):
        #属性
        #直接定义在类的里面,方法的外面
        num = 0        #也叫属性,叫类属性
        #方法
        def __init__(self,new_name):
                #实例属性
                self.name = new_name
        # 记录创建对象的个数
        #利用类属性共享
                Tool.num += 1


#一个特殊的属性,能够知道这个对象的class,即保存了这个类的引用
#类也占存储空间,叫类对象,对应的类里面的属性,叫做类属性
#类属性和类对象有关系,类属性可以在多个实例对象中共享数据
#创建的对象叫实例对象,里面的属性叫实例属性
#实例属性和具体对象有关系,和另外一个实例对象不共享属性
too11 = Tool("铁锹")
tool2 = Tool("工兵铲")
tool3 = Tool("水桶")

print(Tool.num)

1-27 实例方法、类方法和静态方法
class Game(object):
        #类属性
        num = 0

        #实例方法
        def __init__(self):
                #实例属性
                self.name = "laowang"
                Game.num += 1 #访问类属性

        #第二种方法访问类属性,实例属性可以用实例方法来修改,get,add
        #同理,类属性也可以用类方法来修改

        #变成了类方法
        @classmethod  #装饰器
        def add_num(cls):        #类方法中用cls,也可以改成其他的
                cls.num = 100

        '''def print_menu():
                print("****************")
                print("  穿越火线  ")
                print("1.开始游戏")
                print("2.结束游戏")
                print("****************")

        #既有函数又有类,不是很好
        '''

#变成了实例方法,需要写self,但是这个函数又不用,这时候不用写参数,加上@staticmethod,变成静态方法

        @staticmethod
        def print_menu():
                print("****************")
                print("  穿越火线  ")
                print("1.开始游戏")
     &nbsȍ2*].QEȍ2*].p;    print("2.结束游戏")
                print("****************")


# 既有函数又有类,最好只用一种,可以将这个函数放进类里面去



#调用类方法
game = Game()
#可以通过类的名字调用类方法
Game.add_num()

#还可以通过这个类创建出来的对象去调用这个类方法
game.add_num()
print(Game.num)

#调用静态方法
Game.print_menu()
game.print_menu()



回复

0

主题

9

帖子

110

积分

注册会员

Action

Rank: 2

积分
110
Action 发表于 2017-8-10 22:54:13
快点更新吧
回复

63

主题

95

帖子

502

积分

超级版主

谷子老师

Rank: 8Rank: 8

积分
502
谷子老师 发表于 2017-12-6 10:25:16
必须支持一下
回复

0

主题

6

帖子

18

积分

新手上路

bxg_31417

Rank: 1

积分
18
bxg_31417 发表于 2018-5-2 16:14:52
Chenke 发表于 2017-8-3 00:13
2017/8/2 学习笔记

5-1 引用

好啊啊啊啊啊啊啊啊
回复

您需要登录后才可以回帖 登录 | 立即注册