Python基础知识(一)
前言
为了更加熟练的使用PySpark开发业务,以下对python基础知识进行整理
环境安装
1. mac采用brew安装
# 安装python3
brew install python3
2. 安装pip3
pip3 是一个包管理器,用于管理用 Python 编程语言编写的包。要安装 pip3 包管理器,我们必须先下载 get-pip.py 文件并将其保存在 Python 安装目录中。使用下面的命令下载 get-pip.py 文件。
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
现在,我们只需要运行 get-pip.py 文件,它就会自动在我们的 Mac 设备上安装 pip3 包管理器。下面给出了运行 get-pip.py 文件的命令。
python3 get-pip.py
3. 修改pip 镜像源
# 进入根目录
cd ~/
# 进入.pip目录
cd .pip
# 如果不存在文件夹就新建
mkdir .pip
# 进入
cd .pip
# 创建pip.conf文件
touch pip.conf
# 修改
vim pip.conf
文件内容如下
[global]
index-url=http://mirrors.aliyun.com/pypi/simple/
[install]
trusted-host=mirrors.aliyun.com
临时指定pip源
pip install xxx -i http://mirrors.aliyun.com/pypi/simple
内置数据类型
- Numbers(数字)
- String(字符串)
- List(列表)
- Tuple(元组)
- Dictionary(字典)
注:元组是另一个数据类型,类似于 List(列表),但是它不能二次赋值,相当于只读列表。
魔法函数
python是基于协议进行编程的,魔法函数(Magic Methods)是系统进行调用的,类似于Java中的hashCode()方法。常用的魔法函数如下:
python魔法函数
类和对象
1. 鸭子类型和多态
当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。换言之,python中有共同的方法,就可以当作多态来使用,应该python是弱类型语言嘛。
2. 抽象基类(abc模板)
abc是abstract basic class的缩写,跟Java中的接口和抽象类比较像,python是动态语言,没有变量类型的概念。
3. 类变量和实例变量
类变量是在类中声明的、实例变量是在init方法中声明的,对象查找字段的顺序是先从实例中查找,找不到再去查询类变量。
# aaa为类变量
# x、y为实例变量
class A:
aaa = 1
def __init__(self, x, y):
self.x = x
self.y = y
a = A(2, 3)
print(a.x, a.y, a.aaa)
print(A.aaa)
4. 静态方法、类方法以及对象方法
# coding=utf-8
class Date:
# 构造方法
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day
# 实例方法
def tomorrow(self):
self.day += 1
@staticmethod
def parse_from_string(date_str):
year, month, day = tuple(date_str.split("-"))
return Date(int(year), int(month), int(day))
@classmethod
def from_string(cls, date_str):
year, month, day = tuple(date_str.split("-"))
return cls(int(year), int(month), int(day))
def __str__(self):
return "{year}/{month}/{day}".format(year=self.year, month=self.month, day=self.day)
if __name__ == '__main__':
new_day = Date(2021, 11, 10)
new_day.tomorrow()
print new_day
date_str = "2021-11-11"
new_day = Date.parse_from_string(date_str)
print new_day
new_day = Date.from_string(date_str)
print new_day
序列化类
所谓序列,指的是一块可存放多个值的连续内存空间,这些值按一定顺序排列,可通过每个值所在位置的编号(称为索引)访问它们。
为了更形象的认识序列,可以将它看做是一家旅店,那么店中的每个房间就如同序列存储数据的一个个内存空间,每个房间所特有的房间号就相当于索引值。也就是说,通过房间号(索引)我们可以找到这家旅店(序列)中的每个房间(内存空间)。
在 python中,序列类型包括字符串、列表、元组、集合和字典,这些序列支持以下几种通用的操作,但比较特殊的是,集合和字典不支持索引、切片、相加和相乘操作。
1. 序列切片
切片操作是访问序列中元素的另一种方法,它可以访问一定范围内的元素,通过切片操作,可以生成一个新的序列。
语法格式 : sname[start : end : step]
- sname:表示序列的名称;
- start:表示切片的开始索引位置(包括该位置),此参数也可以不指定,会默认为 0,也就是从序列的开头进行切片;
- end:表示切片的结束索引位置(不包括该位置),如果不指定,则默认为序列的长度;
- step:表示在切片过程中,隔几个存储位置(包含当前位置)取一次元素,也就是说,如果 step 的值大于 1,则在进行切片去序列元素时,会“跳跃式”的取元素。如果省略设置 step 的值,则最后一个冒号就可以省略。
2. 序列相加
str1 = 'hello '
str2 = 'david!'
list1 = [1, 2, 3, 4]
list2 = [5, 6, 7, 8]
if __name__ == '__main__':
print str1 + str2
print list1 + list2
list1.extend(list2)
print list1
3. 序列分类
- 容器序列:list、tuple、deque
- 扁平序列:str、bytes、bytearray、array
- 可变序列:list、deque、bytearray、array
- 不可变序列:str、tuple、bytes
4. bisect管理可排序序列
# coding=utf-8
import bisect
# 用来处理已排序的序列,用来维持已排序的序列,升序
# 二分查找
inter_list = []
bisect.insort(inter_list, 3)
bisect.insort(inter_list, 1)
bisect.insort(inter_list, 5)
bisect.insort(inter_list, 2)
bisect.insort(inter_list, 4)
if __name__ == '__main__':
print inter_list
print (bisect.bisect_left(inter_list, 3))
5. 列式推导式、生成器表达式、字典推导式
# coding=utf-8
# 列表生成式(列表推导式)
# 1. 提取出1-20之间的奇数
odd_list = []
for i in range(21):
if i % 2 == 1:
odd_list.append(i)
odd_list = [i for i in range(21) if i % 2 == 1]
# 逻辑复杂的情况
def hadle_item(item):
return item * item
odd_list = [hadle_item(i) for i in range(21) if i % 2 == 1]
# 列表生成器性能高于列表操作
print(type(odd_list))
print(odd_list)
# 生成器表达式
odd_gen = [i for i in range(21) if 1 % 2 == 1]
odd_list = list(odd_gen)
print(type(odd_list))
print(odd_list)
# 字典推导式
my_dict = {"david": 18, "dany": 30, "vivi": 20}
reversed_dict = {value: key for key, value in my_dict.items()}
print(reversed_dict)
# 集合推导式
my_set = {key for key, value in my_dict.items()}
print(type(my_set))
print(my_set)
set和dict
可以查看collections中的abc继承关系,查看它们继承了哪些魔法函数,即实现了哪些协议
a = {"bob1": {"age": 15}, "bob2": {"age": 20}}
# copy, 返回浅拷贝
new_dict = a.copy()
# formkeys
new_list = ["bob1", "bob2"]
new_dict = dict.fromkeys(new_list, {"age": 30})
# 不建议直接继承list和dict,可以继承collection中它们的子类,应该list、dict是C写的,子类UserDict、DefaultDict是按照其逻辑采用python实现了的
# set 集合
# fronzenset (不可变 集合) 无序、不重复
s = set('abcdefg')
f = frozenset("abcedf")
print s
print f
# 向s中添加数据
another_set = set('xyz')
s.update(another_set)
print s
注:list、dict底层都是C语言写的
对象引用、可变性和垃圾回收
# python和java中的变量本质不一样,python的变量实质上是一个指针
a = 1
a = 'abc'
# 1. a贴在1上面
# 2. 首先生成对象,然后将指针存在a中
a = [1, 2, 3]
b = a
print (id(a), id(b))
a = [1, 2, 3, 4]
b = [1, 2, 3, 4]
# 会调用__eq__魔法函数
print a == b
print (id(a), id(b))
print a is b
# python中垃圾回收采用的算法是引用计数法
a = object()
b = a
# 暂时不会回收object的
del a
class A:
# 该魔法函数会在垃圾回收对象的时候调用
def __del__(self):
pass
元类编程
1. property动态属性、getattr、getattribute魔法函数
from datetime import date, datetime
class User:
def __init__(self, name, birthday):
self.name = name
self.birthday = birthday
self._age = 0
# 装饰器
@property
def age(self):
return datetime.now().year - self.birthday.year
@age.setter
def age(self, value):
self._age = value
# __getattr__,getattribute__
# __getattr__是在查找不到属性的时候调用
class User2:
def __init__(self, info={}):
self.info = info
def __getattr__(self, item):
return self.info[item]
# 找不到属性时候首先访问这块,能不重写尽量不要重写
def __getattribute__(self, item):
return "boby"
if __name__ == '__main__':
user = User("bobby", date(year=2020, month=11, day=10))
user._age = 20
print(user.age)
print(user._age)
user2 = User2(info={"company_name": "yidu", "name": "david"})
print(user2.name)
2. new和init魔法函数的区别
class User3:
# 先调用,参数为类
def __new__(cls, *args, **kwargs):
print("in new")
# 后调用,参数为对象,实际上是在此方法中调用__new__
def __init__(self, name):
self.name = name
if __name__ == '__main__':
user3 = User3()
3. 自定义元类
# 类也是对象,type是创建类的类
def create_class(name):
if name == "user":
class User:
def __str__(self):
return "user"
return User
elif name == "company":
class Company:
def __str__(self):
return "company"
return Company
# type动态创建类
User = type("User", (), {})
def say(self):
# return "I an user"
return self.name
class BaseClass:
def answer(self):
return "i am baseclass"
# 元类是创建类的类,比如type可以创建类,然后通过类创建对象
if __name__ == '__main__':
MyClass = create_class("user")
my_obj = MyClass()
print(my_obj)
# 动态创建类,然后实例话
User = type("User", (BaseClass,), {"name": "user", "say": say})
my_obj = User()
print(my_obj.name)
print(my_obj.say())
print(my_obj.answer())
结
python 真香,处理数据很方便。