Python入门(下)

一、简介

Python是一种通用编程语言,其在科学计算和机器学习领域具有广泛的应用。如果我们打算利用python来执行机器学习,那么对python有一些基本的了解就是至关重要的。本python入门系列体验就是为这样的初学者精心准备的。

二、函数

1.函数的定义

还记得python里面的“万物皆对象”么?python把函数也当成对象,可以从另一个函数中返回出来而去构建高阶函数,比如:参数是函数、返回值是函数。
我们首先来介绍函数的定义。

  • 函数以def关键词开头,后接函数名和圆括号()。
  • 函数执行的代码以冒号起始,并且缩进。
  • return [表达式]结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回None。
    def functionname(parameters):
    “函数文档字符串”
    functionsuite
    return [expression]

2.函数的调用

【例子】

def printma(str):
	print(str)
printme('我要调用用户自定义函数') #我要调用用户自定义函数
temp = printme('hello')#hello
print(temp) #None

3.函数文档

def MyFirstFunction(name):
	"函数定义过程中name只是形参"
	#因为它只是一个形式,表示占据一个参数位置
	print('传递进来的{0}叫做实参,因为它是具体的参数值'.format(name))
MyFirstFunction('老马的程序人生')
#传递进来的老马的程序人生叫做实参,因为它是具体的参数值
print(MyFirstFunction.__doc__)
#函数定义过程中name是形参
help(MyFirstFunction)
#Help on function MyFirstFunction in module __main__:

#MyFirstFunction(name)
#     函数定义过程中name只是形参

4.函数参数

python的函数具有非常灵活多样的参数形态,既可以实现简单的调用,又可以传入非常复杂的参数,从简到繁的参数形态如下:

  • 位置参数(position argument)

  • 默认参数(default argument)

  • 可变参数(variable argument)

  • 关键字参数(keyword argument)

  • 命名关键字参数(name keyword argument)

  • 参数组合
    1.位置参数
    def functionname(arg1):
    “函数文档字符串”
    functionsuite
    return [expression]

  • arg1 - 位置参数,这些参数在调用函数(call function)时位置要固定。
    2.默认参数
    def functionname(arg1,arg2=v):
    “函数文档字符串”
    functionsuite
    return [expression]

  • arg2 = v - 默认参数 = 默认值,调用函数时,默认参数的值如果没有传入,则被认为是默认值。

  • 默认参数一定要放在位置参数后面,不然程序会报错。

  • python允许函数调用时参数的顺序与声明时不一致,因为python解释器能够用参数名匹配参数值。
    3.可变参数
    顾名思义,可变参数就是传入的参数个数是可变的,可以是0,1,2到任意个,是不定长的参数。
    def functionname(arg1,arg2=v,*args):
    “函数文档字符串”
    functionsuite
    return [expression]

  • *args - 可变参数,可以是从零个到任意个,自动组装成元组。

  • 加了星号(*)的变量名会存放所有未命名的变量参数。
    【例子】

def printinfo(arg1,*args):
	print(arg1)
	for var in args:
		print(var)
printinfo(10)#10
printinfo(70,60,50)
#70
#60
#50

4.关键字参数
def functionname(arg1,arg2=v,*args,**kw):
“函数文档字符串”
functionsuite
return [expression]

  • **kw-关键字参数,可以是从零个到任意个,自动组装成字典。
    【例子】
def printinfo(arg1,*args,**kwargs):
	print(arg1)
	print(args)
	print(kwargs)
printinfo(70,60,50)
#70
#(60,50)
#{}
printinfo(70,60,50,a=1,b=2)
#70
#(60,50)
#{'a':1,'b':2}

可变参数和关键字参数的异同总结如下:

  • 可变参数允许传入零个到任意个参数,它们在函数调用时自动组装为一个元组(tuple)。

  • 关键字参数允许传入零个到任意个参数,它们在函数内部自动组装为一个字典(dict)。
    5.命名关键字参数
    def functionname(arg1,arg2=v,args,*,nkw,*kw):
    “函数文档字符串”
    functionsuite
    return [expression]

  • *,nkw -命名关键字参数,用户想要输入的关键字参数,定义方式是在nkw前面加个分隔符 *。

  • 如果要限制关键字参数的名字,就可以用命名关键字参数。

  • 使用命名关键字参数时,要特别注意不能缺少参数名。
    【例子】

def printinfo(arg1,*,nkw,**kwargs):
	print(arg1)
	print(nkw)
	print(kwargs)
printinfo(70,nkw=10,a=1,b=2)
#70
#10
#{'a':1,'b':2}
printinfo(70,10,a=1,b=2)
#TypeError: printinfo() takes 1 positional argument but 2 were given
  • 没有写参数名nwk,因此10被当成[位置参数],而原函数只有一个位置参数,现在调用了2个,因此程序会报错。
    6.参数组合
    在python中定义函数,可以用位置参数、默认参数、可变参数、命名关键字参数和关键字参数,这5种参数中的4个都可以一起使用,但是注意,参数定义的顺序必须是:

  • 位置参数、默认参数、可变参数和关键字参数。

  • 位置参数、默认参数、命名关键字参数和关键字参数。
    要注意定义可变参数和关键字参数的语法:

  • *args 是可变参数,args接收的是一个tuple

  • **kw是关键字参数,kw接收的是一个dict
    命名关键字参数是为了限制调用者可以传入的参数名,同时可以提供默认值。定义命名关键字参数不要忘了写分隔符*,否则定义的是位置参数。
    警告:虽然可以组合多达5种参数,但不要同时使用太多的组合,否则函数很难懂。

5.函数的返回值

【例子】

def add(a,b):
	return a + b
print(add(1,2)) #3
print(add([1,2,3],[4,5,6])) #[1,2,3,4,5,6]

【例子】

def back(a,b):
	return [1,'小马的程序人生'3.14]
print(back()) #[1,'小马的程序人生',3.14]

【例子】

def back():
	return 1,'小马的程序人生'3.14
print(back()) #(1,'小马的程序人生',3.14)

【例子】

def printme(str):
	print(str)
temp = printme('hello') #hello
print(temp) #None
print(type(temp)) #<class 'NoneType'>

6.变量作用域

  • python中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的。
  • 定义在函数内部的变量拥有局部作用域,该变量称为局部变量。
  • 定义在函数外部的变量拥有全局作用域,该变量称为全局变量。
  • 局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。
    【例子】
def discounts(price,rate):
	final_price = price * rate
	return final_price
old_price = float(input('请输入原价:')) #98
rate = float(input('请输入折扣率:')) #0.9
new_price = discounts(old_price,rate)
print('打折后价格是:%。2f' % new_price) #88.20
  • 当内部作用域想修改外部作用域的变量时,就要用到global和nonlocal关键字了。
    【例子】
num = 1
def fun1():
	global num #需要使用global关键字声明
	print(num) #1
	num = 123
	print(num) #123
fun1()
print(num)#123

内嵌函数
【例子】

def outer():
	print('outer函数在这被调用')

	def inner():
		print('inner函数在这被调用')
	inner() #该函数只能在outer函数内部被调用
outer()
#outer函数在这被调用
#inner函数在这被调用	

闭包

  • 是函数式编程的一个重要的语法结构,是一种特殊的内嵌函数。
  • 如果在一个内部函数里对外层非全局作用域的变量进行引用,那么内部函数就被认为是闭包。
  • 通过闭包可以访问外层非全局作用域的变量,这个作用域称为闭包作用域。
    【例子】
def funX(x):
	def funY(y):
		return x * y
	return funY

i = funX(8)
print(type(i)) #<class 'function'>
print(i(5)) #40

【例子】闭包的返回值通常是函数。

def make_counter(init):
	counter = [init]
	def inc(): counter[0] += 1
	def dec(): counter[0] -= 1
	def get(): return counter[0]
	def reset(): counter[0] = init
	return inc,dec,get,reset

inc,dec,get,reset = make_counter(0)
inc()
inc()
inc()
print(get())#3
dec()
print(get())#2
reset()
print(get())#0

【例子】如果要修改闭包作用域中的变量则需要nonlocal关键字

def outer():
	num = 10
	def inner():
		nonlocal num #nonlocal关键字声明
		num = 100
		print(num)
	inner()
	print(num)
outer()
#100
#100

递归
-如果一个函数在内部调用自身本身,这个函数就是递归函数。
【例子】n != 1 × 2 × 3 × … × n

#利用循环
n = 5
for k in range(1,5):
	n = n*k
print(n) #120
#利用递归
def factorial(n):
	if n == 1:
		return 1
	return n * factorial(n-1)
print(factorial(5)) #120

【例子】斐波那契数列 f(n)=f(n-1)+f(n-2),f(0)=0 f(1)=1

#利用循环
i = 0
j = 1
lst = list([i,j])
for k in range(2,11):
	k = i + j
	lst.append(k)
	i = j
	j = k
print(lst)
#[0,1,1,2,3,5,8,13,21,34,55]

#利用递归
def recur_fibo(n):
	if n <= 1:
		return n
	return recur_fibo(n-1) + recur_fibo(n-2)

lst = list()
for k in range(11):
	lst.append(recur_fibo(k))

【例子】设置递归的层数,python默认递归层数为100

import sys
sys.setrecursionlimit(1000)

三、Lambda-表达式

1.匿名函数的定义

在python里有两类函数:

  • 第一类:用def关键词定义的正规函数

  • 第二类:用lambda关键词定义的匿名函数
    python使用lambda关键词来创建匿名函数,而非def关键词,它没有函数名,其语法结构如下:
    lambda argument_list: expression

  • lambda -定义匿名函数的关键词

  • argument——list -函数参数,它们可以是位置参数、默认参数、关键字参数,和正规函数里的参数类型一样。

  • :-冒号,在函数参数和表达式中间要加个冒号。

  • expression -只是一个表达式,输入函数参数,输出一些值。
    注意:

  • expression 中没有return语句,因为lambda不需要它来返回,表达式本身结果就是返回值。

  • 匿名函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
    【例子】

def sqr(x) :
 	return x ** 2
 print(sqr)
#<function sqr at 0x03F7F588>
y = [sqr(x) for x in range(10)]
print(y)
#[0,1,4,9,16,25,36,49,64,81]

lbd_sqr = lambda x:x ** 2
print(lbd_sqr)
#<function <lambda> at 0x03682270>
y = [lbd_sqr(x) for x in range(10)]
print(y)
#[0,1,4,9,16,25,36,49,64,81]

sumary = lambda arg1, arg2: arg1 + arg2
print(sumary(10,20)) #30

func = lambda *args:sum(args)
print(func(1,2,3,4,5)) #15

2.匿名函数的应用

函数式编程 是指代码中每一块都是不可变的,都由纯函数的形式组成。这里的纯函数,是指函数本身相互独立、互不影响,对于相同的输入,总会有相同的输出,没有任何副作用。

【例子】非函数式编程

def f(x):
	for i in range(0,len(x)):
		x[i] += 10
	return x
x = [1,2,3]
f(x)
print(x)
#[11,12,13]

【例子】函数式编程

def f(x):
	y = []
	for item in x:
		y.append(item + 10)
	return y
x = [1,2,3]
f(x)
print(x)
#[1,2,3]

匿名函数 常常应用于函数式编程的高阶函数(high-order function)中,主要有两种形式:

  • 参数是函数(filter,map)

  • 返回值是函数(closure)
    如,在filter 和map函数中的应用:

  • filter(function, iterable)过滤序列,过滤掉不符合条件的元素,返回一个迭代器对象,如果要转换为列表,可以使用list()来转换。
    【例子】

odd = lambda x: x % 2 == 1
templist = filter(odd,[1,2,3,4,5,6,7,8,9])
print(list(templist)) #[1,3,5,7,9]
  • map(function, *iterables)根据提供的函数对指定序列做映射。
    【例子】
m1 = map(lambda x: x**2,[1,2,3,4,5])
print(list(m1))
#[1,4,9,16,25]

m2 = map(lambda x,y: x + y,[1,3,5,7,9],[2,4,6,8,10])
print(list(m2))
#[3,7,11,15,19]

除了python这些内置函数,我们也可以自己定义高阶函数。
【例子】

def apply_to_list(fun,some_list):
	return fun(some_list)
lst = [1,2,3,4,5]
print(apply_to_list(sum,lst))
#15
print(apply_to_list(len,lst))
#5
print(apply_to_list(lambda x: sum(x)/len(x),lst))
#3.0

四、类与对象

1.属性和方法组成对象

对象 = 属性 + 方法
对象是类的实例。换句话说,类主要定义对象的结构,然后我们以类为模板创建对象。类不但包含方法定义,而且还包含所有实例共享的数据。

  • 封装:信息隐蔽技术
    我们可以使用关键字class定义python类,关键字后面紧跟类的名称、分号和类的实现。

  • 继承:子类自动共享父类之间数据和方法的机制

  • 多态:不同对象对同一方法响应不同的行动
    【例子】

class Animal:
	def run(self):
		raise AttributeError('子类必须实现这个方法')
class People(Animal):
	def run(self):
		print('人正在走')
class Pig(Animal):
	def run(self):
		print('pig is walking')
def func(animal):
	animal.run()
func(Pig())
#pig is walking

2.self是什么?

python的self相当于C++的this指针。

class Test:
	def prt(self):
		print(self)
		print(self.__class__)
t = Test()
t.prt()
#<__main__.Test object at 0x03636C30>
#<class '__main__.Test'>

类的方法与普通的函数只有一个特别的区别 – 它们必须有一个额外的第一个参数名称(对应于该实例,即该对象本身),按照惯例它的名称是self。在调用方法时,我们无需明确提供与参数self相对应的参数。
【例子】

class Ball:
	def setName(self,name):
		self.name = name
	def kick(self):
		print("我叫%s,谁踢我" % self.name)
a = Ball()
a.setName("球A")
b = Ball()
b.setName("球B")
c = Ball()
c.setName("球C")
a.kick()
#我叫球A,谁踢我
#我叫球B,谁踢我

3.Python的魔法方法

据说,python的对象天生拥有一些神奇的方法,它们是面向对象的python的一切。
它们是可以给你的类增加魔力的特殊方法。
如果你的对象实现了这些方法中的某一个,那么这个方法就会在特殊的情况下被python所调用,而这一切都是自动发生的。
类有一个名为__init__(self[,param1,param2…])的魔法方法,该方法在类实例化时会自动调用。
【例子】

class Ball:
	def __init__(self,name):
		self.name = name
	def kick(self):
		print('我叫%s' % self.name)
a = Ball('球A')
b = Ball('球B')
c = Ball('球C')
a.kick()
#我叫球A
b.kick()
#我叫球B

4.公有和私有

在python中定义私有变量只需要在变量名或函数名前加上"__"两个下划线,那么这个函数或变量就会为私有的了。
【例子】类的私有属性实例

class JustCounter:
	__secretCount = 0 #私有变量
	publicCount = 0 #公开变量
	def count(self):
		self.__secretCount += 1
		self.publicCount += 1
		print(self.__secretCount)
couter = JustCounter()
counter.count() #1
counter.count() #2
print(counter.publicCount) #2

#python的私有为伪私有
print(counter.__JustCounter__secretCount) #2
print(counter.__secretCount)
# AttributeError: 'JustCounter' object has no attribute '__secretCount'

【例子】类的私有方法实例

class Site:
	def __init__(self,name,url):
		self.name = name #public
		self.__url = url #private
	def who(self):
		print('name:',self.name)
		print('url:',self.__url)
	def __foo(self):#私有方法
		print('这是私有方法')
	def foo(self):#公有方法
		print('这是公有方法')
		self.__foo()
x = Site('老马的程序人生',‘https://blog.csdn.net/lsgo’)
x.who()
#name:老马的程序人生
#url:https://blog.csdn.net/lsgo
x.foo()
#这是公共方法
#这是私有方法
x.__foo()
# AttributeError:'Site' object has no attribute '__foo'

5.继承

python同样支持类的继承,派生类的定义如下所示:
class DerivedClassName(BaseClassName):
statement -1
.
.
.
statement -N
BaseClassName(基类名)必须与派生类定义在一个作用域内。除了类,还可以用表达式,基类定义在另一个模块中时这一点非常有用:
class DerivedClassName(modname.BaseClassName):
statement -1
.
.
.
statement -N
【例子】如果子类中定义与父类同名的方法或属性,则会自动覆盖父类对应的方法或属性。

#类定义
class people:
    #定义基本属性
    name = ''
    age = 0
    # 定义私有属性,私有属性在类外部无法直接进行访问
    __weight = 0
    #定义构造方法
    def __init__(self,n,a,w):
        self.name = n
        self.age = a
        self.__weight = w
    def speak(self):
        print("%s 说:我 %d 岁。" % (self.name,self.age))
#单继承示例
class student(people):
    grade = ''
    def __init__(self,n,a,w,g):
        #调用父类的构函
        people.__init__(self,n,a,w)
        self.grade = g
        #覆写父类的方法
    def speak(self):
        print("%s 说:我 %d 岁,我在读 %d 年级。" % (self.name,self.age,self.grade))
s = student('小马的程序人生',10,60,3)
s.speak()
#小马的程序人生说:我10岁了,我在读3年级

注意:如果上面的程序去掉:people._init_(self,n,a,w),则输出:说:我0岁了,我在读3年级,因为子类的构造方法把父类的构造方法覆盖了。
【例子】

import random

class Fish:
    def __init__(self):
        self.x = random.randint(0,10)
        self.y = random.randint(0,10)
    def move(self):
        self.x -= 1
        print('我的位置',self.x,self.y)
class GoldFish(Fish): #金鱼
    pass
class Carp(Fish):#鲤鱼
    pass
class Salmon(Fish):#三文鱼
    pass
class Shark(Fish):#鲨鱼
    def __init__(self):
        self.hungry = True
    def eat(self):
        if self.hungry:
            print('吃货的梦想就是天天有得吃!')
        else:
            print('太撑了,吃不下了!')
            self.hungry = True
g = GoldFish()
g.move() #我们位置 9 4
s = Shark()
s.eat() #吃货的梦想就是天天有得吃!
s.move()#AttributeError: 'Shark' object has no attribute 'x'

解决该问题可用以下两种方式:

  • 调用未绑定的父类方法Fish._init_(self)
class Shark(Fish):#鲨鱼
	def __init__(self):
		Fish.__init__(self)
		self.hungry = True
	def eat(self):
		if self.hungry:
			print('吃货的梦想就是天天有得吃!')
			self.hungry = False
		else:
			print('太撑了,吃不下了!')
			self.hungry = True
  • 使用super函数super()._init_()
class Shark(Fish):#鲨鱼
	def __init__(self):
		super().__init__()
		self.hungry = True
	def eat(self):
		if self.hungry:
			print('吃货的梦想就是天天有得吃!')
			self.hungry = False
		else:
			print('太撑了,吃不下了!')
			self.hungry = True

python虽然支持多继承的形式,但我们一般不使用多继承,因为容易引起混乱。
class DerivedClassName(Base1,Base2,Base3):
statement -1
.
.
.
statement -N

需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,python从左到右搜素,即方法在子类中未找到时,从左到右查找父类中是否包含方法。
【例子】

#类定义
class People:
	#定义基本属性
	name = ''
	age = 0
	#定义私有属性,私有属性在类外部无法直接进行访问
	__weight = 0
	#定义构造方法
	def __init__(self,n,a,w):
		self.name = n
		self.age = a
		self.__weight = w
	def speak(self):
		print("%s 说: 我 %d 岁。" % (self.name,self.age))
#单继承示例
class Student(People):
	grade = ''
	def __init__(self,n,a,w,g):
	#调用父类的构函
	People.__init__(self,n,a,w)
	self.grade = g
#覆写父类的方法
def speak(self):
	print("%s 说: 我 %d 岁了,我在读 %d 年级" %(self.name,self.age,self.grade))
#另一个类,多重继承之前的准备
class Speaker:
	topic = ''
	name = ''
	def __init__(self,n,t):
		self.name = n
		self.topic = t
	def speak(self):
		print("我叫 %s,我是一个演说家,我演讲的主题是 %s" %(self.name,self.topic))
#多重继承
class Sample01(Speaker,Student):
	a = ''
	def __init__(self,n,a,w,g,t):
		Student.__init__(self,n,a,w,g)
		Speaker.__init__(self,n,t)
#方法名同,默认调用的是在括号中排前面的父类的方法
test = Sample01('Tim',25,80,4,'python')
test.speak()
#我叫Tim,我是一个演说家,我演讲的主题是python

class Sample02(Student,Speaker):
	a = ''
	def __init__(self,n,a,w,g,t):
		Student.__init__(self,n,a,w,g)
		Speaker.__init__(self,n,t)
#方法名同,默认调用的是在括号中排前面的父类的方法
test = Sample01('Tim',25,80,4,'python')
test.speak()
#Tim说:我25岁了,我在读4年级

6.组合

【例子】

class Turtle:
	def __init__(self,x):
		self.num = x
class Fish:
	def __init__(self,x):
		self.num = x
class Pool:
	def __init__(self,x,y):
		self.turtle = Turtle(x)
		self.fish = Fish(y)
	def print_num(self):
		print('水池里面有乌龟%s只,小鱼%s条'%(self.turtle.num,self.fish.num))
p = Pool(2,3)
p.print_num()
#水池里面有乌龟2只,小鱼3条

7.类、类对象和实例对象

在这里插入图片描述
类对象:创建一个类,其实也是一个对象,也在内存开辟了一块空间,称为类对象,类对象只有一个。
class A(object):
pass
实例对象:就是通过实例化类创建的对象,称为实例对象,实例对象可以有多个。
【例子】

class A(object):
	pass
#实例化对象a、b、c都属于实例对象。
a = A()
b = A()
c = A()

类属性:类里面方法外面定义的变量称为类属性,类属性所属于类对象并且多个实例对象之间共享同一个类属性,说白了就是类属性所有的通过该类实例化的对象都能共享。

【例子】

class A():
	a = 0 #类属性
	def __init__(self,xx):
		A.a = xx #使用类属性可以通过(类名.类属性)调用。

实例属性:实例属性和具体的某个实例对象有关系,并且一个实例对象和另一个实例对象是不共享属性的,说白了实例属性只能在自己的对象里面使用,其他对象不能直接使用,因为self是谁调用,它的值就属于该对象。
【例子】

#创建类对象
class Test(object):
	class_attr = 100 #类属性
	def __init__(self):
		self.sl_attr = 100 #实例属性
	def func(self):
		print('类对象.类属性的值:',Test.class_attr) #调用类属性
		print('self.类属性的值',self.class_attr) #相当于把类属性 变成实例属性
		print('self.实例属性的值',self.sl_attr) #调用实例属性
	
a = Test()
a.func()

#类对象.类属性的值:100
#self.类属性的值 100
#self.实例属性的值 100

b = Test()
b.func()
#类对象.类属性的值:100
#self.类属性的值 100
#self.实例属性的值 100
a.class_attr = 200
a.sl_attr = 200
a.func()

#类对象.类属性的值:100
#self.类属性的值 200
#self.实例属性的值 200

b.func()
#类对象.类属性的值:100
#self.类属性的值 100
#self.实例属性的值 100

Test.class_attr = 300
a.func()

#类对象.类属性的值:300
#self.类属性的值 200
#self.实例属性的值 200

b.func()
#类对象.类属性的值:300
#self.类属性的值 300
#self.实例属性的值 100

注意:属性与方法名相同,属性会覆盖方法。

【例子】

class A:
	def x(self):
		print('x_man')
aa = A()
aa.x() #x_man
aa.x = 1
print(aa.x) #1
aa.x
#TypeError:'int' object is not callable

8.什么是绑定

python严格要求方法需要有实例才能被调用,这种限制其实就是python所谓的绑定概念。
python 对象的数据属性通常存储在名为. _dict_ 的字典中,我们可以直接访问_dict_,或利用python的内置函数vars()获取. _dict_ 。
【例子】

class CC:
	def setXY(self,x,y):
		self.x = x
		self.y = y
	def printXY(self):
		print(self.x,sele.y)

dd = CC()
print(dd.__dict__ ) #{}
print(vars(add)) #{}
print(CC.__dict__ ) 
#{'__module__': '__main__', 'setXY': <function CC.setXY at 0x0000022C56539400>, 'printXY': <function CC.printXY at 0x0000022C56539488>, '__dict__': <attribute '__dict__' of 'CC' objects>, '__weakref__': <attribute '__weakref__' of 'CC' objects>, '__doc__': None}
dd.setXY(4,5)
print(dd.__dict__)#{'x': 4, 'y': 5}
print(vars(CC))
#{'__module__': '__main__', 'setXY': <function CC.setXY at 0x0000022CCFE99488>, 'printXY': <function CC.printXY at 0x0000022CCFE99840>, '__dict__': <attribute '__dict__' of 'CC' objects>, '__weakref__': <attribute '__weakref__' of 'CC' objects>, '__doc__': None}
print(CC.__dict__ )
#{'__module__': '__main__', 'setXY': <function CC.setXY at 0x0000022CCFE99488>, 'printXY': <function CC.printXY at 0x0000022CCFE99840>, '__dict__': <attribute '__dict__' of 'CC' objects>, '__weakref__': <attribute '__weakref__' of 'CC' objects>, '__doc__': None}

9.一些相关的内置函数(BIF)

  • issubclass(class,classinfo)方法用于判断参数class是否是类型参数classinfo的子类。
  • 一个类被认为是其自身的子类。
  • classinfo可以是类对象的元组,只要class是其中任何一个候选类的子类,则返回True。
    【例子】
class A:
	pass
class B(A):
	pass
print(issubclass(B,A)) #True
print(issubclass(B,B)) #True
print(issubclass(A,B)) #False
print(issubclass(B,object)) #True
  • isinstance(object,classinfo)方法用于判断一个对象是否是一个已知的类型,类似type()。
  • type()不会认为子类是一种父类类型,不考虑继承关系。
  • isinstance()会认为子类是一种父类类型,考虑继承关系。
  • 如果第一个参数不是对象,则永远返回False。
  • 如果第二个参数不是类或者由类对象组成的元组,会抛出一个TypeError异常。
    【例子】
a = 2
print(isinstance(a,int)) #True
print(isinstance(a,str)) #False
print(isinstance(a,(str,int,list))) #True

class A:
	pass
class B:
	pass
print(isinstance(A(),A)) #True
print(type(A())==A) #True
print(isinstance(B(),A)) #True
print(type(B())==A) #False
  • hasattr(object,name)用于判断对象是否包含对应的属性。
    【例子】
class Coordinate:
	x = 10
	y = -5
	z = 0
point1 = Coordinate()
print(hasattr(point1,'x')) #True
print(hasattr(point1,'y')) #True
print(hasattr(point1,'z')) #True
print(hasattr(point1,'no')) #False
  • getattr(object, name[, default])用于返回一个对象属性值。
    【例子】
class A(object):
	bar = 1
a = A()
print(getattr(a,'bar')) #1
print(getattr(a,'bar2',3)) #3
print(getattr(a,'bar2')) 
#AttrbuteError:'A' object has no attribute 'bar2'

【例子】

class A(object):
	def set(self,a,b):
		x = a
		a = b
		b = x
		print(a,b)
a = A()
c = getattr(a,'set')
c(a='1',b='2') #2 1
  • setattr(object, name, value)对应函数getattr(),用于设置属性值,该属性不一定存在的。
    【例子】
class A(object):
	bar = 1
a = A()
print(getattr(a,'bar')) #1
setattr(a,'bar',5)
print(a.bar) #5
setattr(a,'age',28)
print(a.age) #28
  • delattr(object, name)用于删除属性
    【例子】
class Coordinate:
	x = 10
	y = -5
	z = 0
point1 = Coordinate()
print('x = ',point1.x)) #x =10
print('y = ',point1.y)) #y = -5
print('z = ',point1.z)) #z = 0

delattr(Coordinate,'z')
print('--删除z属性后--') #--删除z属性后--
print('x = ',point1.x)) #x =10
print('y = ',point1.y)) #y = -5
#触发错误
print('z = ',point1.z)) 
#AttrbuteError:'Coordinate' object has no attribute 'z'
  • class property([fget[, fset[, fdel[, doc]]]]) 用于在新式类中返回属性值。
  • fget --获取属性值的函数
  • fset --设置属性值的函数
  • fdel --删除属性值函数
  • doc --属性描述信息
    【例子】
class C(object):
	def __init__(self):
		self.__x = None
	def getx(self):
		return self.__x
	def setx(self,value):
		self.__x = value
	def delx(self):
		del self.__x
	x = property(getx,setx,delx,"I'm the 'x' property.")
cc = C()
cc.x = 2
print(cc.x) #2
del cc.x
print(cc.x)
#AttributeError:'C' object has no attribute '__C____x'

五、魔方方法

魔法方法总是被双下划线包围,例如__init__。
魔法方法是面向对象的python的一切,如果你不知道魔法方法,说明你还没意识到面向对象的python的强大。
魔法方法的第一个参数应为cls(类方法)或者self(实例方法)。

  • cls:代表一个类的名称
  • self:代表一个实例对象的名称

1.基本的魔法方法

  • _init_(self[, …])构造器,当一个实例被创建的时候调用的初始化方法
    【例子】
class Rectangele:
	def __init__(self,x,y):
		self.x = x
		self.y = y
	def getPeri(self):
		return (self.x + self.y) * 2
	def getArea(self):
		return self.x * self.y
rect = Rectangle(4,5)
print(rect.getPeri())  #18
print(rect.getArea())  #20
  • _new_(cls[, …]) 在一个对象实例化的时候所调用的第一个方法,在调用_init_ 初始化前,先调用 _new_。
  • _new_ 至少要有一个参数cls,代表要实例化的类,此参数在实例化时由python解释器自动提供,后面的参数直接传递给 _init_。
  • _new_ 对当前类进行了实例化,并将实例返回,传给_init_ ,只有_new_ 返回了当前类cls的实例,当前类的__init__才会进入。

2.算术运算符

类型工厂函数,指的是“不通过类而是通过函数来创建对象”。

3.反算数运算符

反运算魔方方法,与算数运算符保持一一对应,不同之处就是反运算的魔法方法多了一个"r"。当文件左操作不支持相应的操作时被调用。

4.增量赋值运算

在这里插入图片描述

5.一元运算符

在这里插入图片描述

6.属性访问

在这里插入图片描述

7.描述符

在这里插入图片描述

8.定制序列

在这里插入图片描述

9.迭代器

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值