Python初学者学习案例之二

普通人:计划失败 -> 沮丧 -> 骂自己一顿 -> 制订新计划 -> 继续失败

学霸:计划失败 -> 沮丧 -> 骂自己一顿 -> 深度思考计划为啥失败 -> 改善问题 -> 制订新计划


学习思维:案例学习

#!/usr/bin/env python3
# -*- coding: utf-8 -*-


' a test module '

__author__ = '黯雅'


#第1行注释可以让这个hello.py文件直接在Unix/Linux/Mac上运行,第2行注释表示.py文件本身使用标准UTF-8编码
#sys模块有一个argv变量,用list存储了命令行的所有参数。argv至少有一个元素,因为第一个参数永远是该.py文件的名称
#运行python3 hello.py获得的sys.argv就是['hello.py']
import sys

def test():
    args = sys.argv
    if len(args)==1:
        print('Hello, world!')
    elif len(args)==2:
        print('Hello, %s!' % args[1])
    else:
        print('Too many arguments!')


if __name__=='__main__':
    test()

#作用域
#正常的函数和变量名是公开的(public),可以被直接引用比如:abc,x123,PI等
#类似__xxx__这样的变量是特殊变量,可以被直接引用,但是有特殊用途,比如上面的__author__,__name__就是特殊变量,自己的变量一般不要用这种变量名
#_xxx和__xxx这样的函数或变量就是非公开的(private)
#private函数和变量“不应该”被直接引用,而不是“不能”被直接引用,Python并没有一种方法可以完全限制访问private函数或变量
def _private_1(name):
    return 'Hello, %s' % name

def _private_2(name):
    return 'Hi, %s' % name

def greeting(name):
    if len(name) > 3:
        return _private_1(name)
    else:
        return _private_2(name)


print(greeting('黯雅'))

#安装第三方模块
#在Python中,安装第三方模块,是通过包管理工具pip完成的
#第三方库都会在Python官方的pypi.python.org网站注册,要安装一个第三方库,必须先知道该库的名称,可以在官网或者pypi上搜索,比如Pillow的名称叫Pillow
#安装命令 pip install Pillow  等待安装完成


#有了Pillow,处理图片易如反掌
#>>> from PIL import Image
#>>> im = Image.open('test.png')
#>>> print(im.format, im.size, im.mode)
#PNG (400, 300) RGB
#>>> im.thumbnail((200, 100))
#>>> im.save('thumb.jpg', 'JPEG')

import sys
print(sys.path)

#面向对象过程
#定义一个特殊的__init__方法,在创建实例的时候,就把name,score等属性绑上去
#self,表示创建的实例本身
#让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,外部代码要获取修改name和score就getSet方法啊
#object 父类
class Student(object):
    def __init__(self,name,score):
        self._name=name
        self._score=score

    def print_student(self):
        print('%s: %s' % (self._name, self._score))
        print('Message:',self._name,self._score)

    def get_grade(self):
        if self._score >= 20:
            return 'A'
        elif self._score >= 40:
            return 'B'
        else:
            return 'C'

input_mes1 = Student('黯雅',13)
input_mes2 = Student('黯雅',45)
input_mes1.print_student();
print(input_mes1.get_grade())
input_mes2.print_student();
print(input_mes2.get_grade())


#不能直接访问__name是因为Python解释器对外把__name变量改成了_Student__name,所以,仍然可以通过_Student__name来访问__name变量:
#强烈建议你不要这么干,因为不同版本的Python解释器可能会把__name改成不同的变量名
#print(input_mes1._Student__name)
#print(input_mes2._Student__name)

#判断一个变量是否是某个类型可以用isinstance()判断
print(isinstance(input_mes1, Student))
#参数也可传递
def run_twice(animal):
    animal.print_student()

animal = Student('AAA',34)
run_twice(animal)

#--获取对象---type()
#当我们拿到一个对象的引用时,如何知道这个对象是什么类型、有哪些方法呢?
print(type(Student))
print(type(input_mes1))

print(type(123)==type(456))
print(type(123)==int)
print(type('abc')==str)

#判断是否是函数
import types
def fn():
    pass

print('FunctionType ',type(fn)==types.FunctionType)
print('BuiltinFunctionType ',type(abs)==types.BuiltinFunctionType)
print('LambdaType ',type(lambda x: x)==types.LambdaType)
print('GeneratorType ',type((x for x in range(10)))==types.GeneratorType)

#使用isinstance()判断class类型
#isinstance()判断的是一个对象是否是该类型本身,或者位于该类型的父继承链上
print('isinstance ',isinstance(1234, int))
print('isinstance ',isinstance('abc', str))
print('isinstance ',isinstance(input_mes1, Student))
print('多个类型中判断',isinstance([1, 2, 3], (list, tuple)))

#获得一个对象的所有属性和方法
print('获得一个对象的所有属性和方法:',dir(input_mes1))

#在len()函数内部,它自动去调用该对象的__len__()方法,所以是等价的
#print('长度: ',len('ABC'),'ABC'._len_(), 'ABC'.lower())

#配合getattr()、setattr()以及hasattr(),我们可以直接操作一个对象的状态
class MyObject(object):
      def __init__(self):
        self.x = 9
      def power(self):
        return self.x * self.x

print(hasattr(MyObject(),'x'))
setattr(MyObject(), 'y', 19)  # 设置一个属性'y'
print(hasattr(MyObject(),'y'))
print(getattr(MyObject(),'x'))

#--实例属性和类属性---
#接在class中定义属性,这种属性是类属性

class Teacher(object):
    name='Teacher'  #类属性

t = Teacher()

print('打印类属性:',Teacher.name)
t.name='Teacher1'  #由于实例属性优先级比类属性高,因此,它会屏蔽掉类的name属性
print('打印实例属性',t.name)

#面向对象高级编程
#数据封装、继承和多态只是面向对象程序设计中最基础的3个概念,面向对象还有很多高级特性:如多重继承、定制类、元类等概念


#创建了一个class的实例后,我们可以给该实例绑定任何属性和方法,这就是动态语言的灵活性
class Student1(object):
    pass

#给实例绑定一个属性:
s2 = Student1();
s2.name = 'Macal'
print('绑定一个属性',s2.name)


#给实例绑定一个方法:
def set_age(self,age): # 定义一个函数作为实例方法
        self.age = age

from types import MethodType

s2.set_age = MethodType(set_age, s2)#对类实例进行绑定
s2.set_age(20)
print('实例类进行绑定方法',s2.age)

s3 = Student1() #从新建立实例调用,就会报错
#s3.set_age(21)

#对类进行绑定
def set_score(self, score):
         self.score = score

Student1.set_score = set_score #直接对类进行绑定

s3.set_score(23)
print('直接对类进行绑定方法:',s3.score)

#定义一个特殊的__slots__变量,来限制该class实例能添加的属性:
class Student3(object):
    __slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称

s3 = Student3()
s3.name = "MAC"
s3.age = 21
#s3.score =28  报错
print('__slots__变量:',s3.name,s3.age)

#使用@property
#和java一样get set 方法

class Student4(object):
    def set_score(self,value):
        if not isinstance(value, int):
            raise ValueError('score must be an integer!')
        if value < 0 or value > 100:
            raise ValueError('score must between 0 ~ 100!')
        self._score =value
    def get_score(self):
        return self._score
a = Student4()
a.set_score(12)
print('get set 方法:',a.get_score())


#Python内置的@property装饰器就是负责把一个方法变成属性调用的:
class Student5(object):

    @property
    def score(self):
        return self._score

    @score.setter
    def score(self, value):
        if not isinstance(value, int):
            raise ValueError('score must be an integer!')
        if value < 0 or value > 100:
            raise ValueError('score must between 0 ~ 100!')
        self._score = value


s4 = Student5()
s4.score = 40
print('使用property属性:',s4.score)


#练习
#请利用@property给一个Screen对象加上width和height属性,以及一个只读属性resolution:


class Screen(object):
    @property
    def width(self):
        return self._width
    @property
    def height(self):
        return self._height

    @width.setter
    def width(self,value):
        if value < 0 or value > 100:
            raise ValueError('width must between 0 ~ 100!')
        self._width=value

    @height.setter
    def height(self,value):
        if value < 0 or value > 100:
            raise ValueError('height must between 0 ~ 100!')
        self._height=value


    @property
    def resolution(self):
        return 'width:%s,hight:%s,resolution:%s' % (self._width,self._height,self._width*self._height)


f = Screen()
f.height=20
f.width=20
print(f.resolution)







案例2

#!/usr/bin/env python3
# -*- coding: utf-8 -*-


#多继承  (java中一个类只能继承一个父类,但是在python中可以继承多个父类,这就是唯一区别)
#1-0
class animal(object):
    pass


#1-1
class Runable(object):
    def run(self):
        print('Running.....')


class Flying(object):
    def fly(self):
        print('Flying.......')
#2 多继承
class Mammal(animal,Runable):
    pass


class Bird(animal,Flying):
    pass


#3
class Dog(Mammal):
    pass


class Bat(Mammal):
    pass


class Parrot(Bird):
    pass


class Ostrich(Bird):
    pass


#---定制类----
class Student(object):
    def __init__(self,name):
        self._name = name
    def __str__(self):
        return '定制类return values: %s'%self._name
    __repr__ = __str__

s = Student('请 你')
s
print(Student('请 你'))


#----__iter__------
#一个类想被用于for ... in循环,类似list或tuple那样,就必须实现一个__iter__()方法,该方法返回一个迭代对象
#像list那样按照下标取出元素,需要实现__getitem__()方法
#计算斐波那契数列
class Fib(object):
    def __init__(self):
        self.a,self.b = 0,1
    def __iter__(self):
        return self  #实例本身就是迭代对象,故返回自己
    def __next__(self):
        self.a ,self.b = self.b,self.a+self.b
        if self.a>10000:
            raise StopIteration()
        return self.a
    def __getitem__(self, item):
        if isinstance(item, int):  # n是索引
            a, b = 1, 1
            for x in range(item):
                a, b = b, a + b
                return a
        if isinstance(item, slice):  # n是切片
            start = item.start
            stop = item.stop
            if start is None:
                start = 0
            #if stop is None:这里不允许后切片为空的情况。因为是一个一个计算的
            a, b = 1, 1
            L = []
            for x in range(stop):
                if x >= start:
                    L.append(a)
                a, b = b, a + b
            return L

for x in Fib():
    print('函数迭代的值:',x)

print('得到函数下标未4的值:',Fib()[4])
print('函数切片:',Fib()[:15])
print('普通切片:',list(range(11))[2:10])

#----__getattr__---
#当我们调用类的方法或属性时,如果不存在,就会报错,
#当调用不存在的属性时,比如score,Python解释器会试图调用__getattr__(self, 'score')来尝试获得属性,重写这个方法

class Fib1(object):
    def __init__(self,name):
        self._name_ = name
    def __getattr__(self, item):
        if item == 'score':
            return 90
s= Fib1('Macal')
print('调用存在的属性:',s._name_)
print('调用不存在的属性:',s.score)

#---_call()---
#一个对象实例可以有自己的属性和方法
class Student(object):
    def __init__(self, name):
        self.name = name

    def __call__(self):
        print('My name is %s.' % self.name)

s = Student('Milll')
s()

#---使用枚举类---
from enum import Enum
Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))

for name, member in Month.__members__.items():
    print(name, '=>', member, ',', member.value)

from enum import Enum, unique

@unique
class Weekday(Enum):
    Sun = 0 # Sun的value被设定为0
    Mon = 1
    Tue = 2
    Wed = 3
    Thu = 4
    Fri = 5
    Sat = 6

day1 = Weekday.Sun
print(day1)
print(Weekday['Tue'])
print(Weekday['Tue'].value)
print(day1 == Weekday.Sun)
print(Weekday(1))

for name, member in Weekday.__members__.items():
        print(name, '=>', member,member.value)



#!/usr/bin/senv python3
# -*- coding: utf-8 -*-


import os
print(os.name)
print(os.environ)
print(os.environ.get('PATH'))


#查看当前目录的绝对路径:
print(os.path.abspath('.'))
# 在某个目录下创建一个新目录
os.path.join(os.path.abspath('.'),'tnt')
# 然后创建一个目录:
os.makedirs(os.path.abspath('.')+'/tnt')
# 删掉一个目录:
os.rmdir(os.path.abspath('.')+'/tnt')
#通过os.path.split()函数,这样可以把一个路径拆分为两部分,后一部分总是最后级别的目录或文件名
print(os.path.split(os.path.abspath('.')))
#直接让你得到文件扩展名
print(os.path.splitext('.'))


# 对文件重命名:
#os.rename('test.txt', 'test.py')
# 删掉文件:
#os.remove('test.py')


#列出当前目录下的所有目录
print([x for x in os.listdir('.') if os.path.isdir(x)])


#要列出所有的.py文件
print( [x for x in os.listdir('.') if os.path.isfile(x) and os.path.splitext(x)[1]=='.py'])






#----序列化---
#变量从内存中变成可存储或传输的过程称之为序列化(python)
#网络和本地存储在过程中的转化成为序列化(Java)


import pickle
d =dict(name='黯雅',scor=98,age=20)
print(pickle.dumps(d))#pickle.dumps()方法把任意对象序列化成一个bytes
#就可以把这个bytes写入文件。或者用另一个方法pickle.dump()直接把对象序列化后写入一个file-like Object


f = open('1.txt','wb')
pickle.dump(d,f)
f.close()


f = open('1.txt','rb')
d = pickle.load(f)
f.close()
print('pickle序列化:',d)


#注意:它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据,不能成功地反序列化也没关系


#Python的dict对象可以直接序列化为JSON的{}
import json
class Student(object):
    def __init__(self,name,age,score):
        self.name = name
        self.score = score
        self.age = age


def student2dict(st):
    return {
        'name':st.name,
        'age':st.age,
        'score':st.score
    }


s= Student('anya',23,22)
print('json序列化:',json.dumps(s,default=student2dict))




#反序列化 (报错)
def dict2student(st):
    return Student(st['name'],st['age'],st['score'])


json_str={"name":"anya", "age":25, "score":28}
print('json反序列化:',json.loads(json_str,object_hook=dict2student))


如果有兴趣的童鞋,可以加群交流交流:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值