函数变量作用域

本文详细讲解了Python中函数变量的作用域规则,介绍了全局变量与局部变量的区别,重点阐述了面向对象编程的概念,包括封装、继承和多态,以及类的构成、实例化、属性与方法的区别,涉及深浅拷贝和模块导入,还讨论了异常处理的语法。
摘要由CSDN通过智能技术生成
函数变量作用域

a .在一个函数内创建一个变量时,默认情况下它是本地变量

b .在一个函数外定义一个变量时,它是全局变量

c .若在函数内读取一个全局变量时,不需加 global ,但要重新给全局变量赋值,需加 global ;若调用该变量的方法,则可以不用 global ,不算重新赋值

面向对象

1、面向对象:将一件事情首先想象为一个对象,然后提取该对象的所有共同的方法(动作)和属性(函数),利用这些方法和属性来完成该事情

好处:以对象作为程序的基本单元,将方法和属性封装其中,有三个特征:封装 继承 多态,提高重用、灵活、扩展

面向对象的特性:继承、封装、多态

封装:将对象的内部细节隐藏起来,通过公用方法来暴露该对象的具体功能
继承:子类继承父类(功能、属性)、还可以重写
多态:在继承的基础上对父类的某个行为复用的一种行为表现。(子类重写父类方法)

类:N多个对象抽取出具有相同属性和方法的对象的总称( Car 、 People )
对象:类的一个实例 car = Car()

2、面向过程:做一件事情,需要按照什么样的过程完成。大象装冰箱

python 里面自定义终极父类 object

self 作用:定义方法时表明当前方法是实例方法,定义要写 self ,调用不用。

类的组成

类属性:直接定义在类中,方法外的变量(通过类名.xx调用),每个实例都可调用

实例属性:定义在__init__方法中,使用self.xx表示(通过对象.xx调用)

实例方法:定义在类中的函数,自带self参数(通过对象.xx调用)

静态方法:@staticmethod修饰的方法(通过类名.xx调用)

类方法:@classmethod修饰的方法(通过类名.xx调用)

实例化对象后 : 实例 = 类名(),自动调用构造函数

实例对象三个特征:值value(所有属性、方法的集合)/地址id/类型type

每个函数后必加self参数,self叫做当前实例

类方法得传入类名或实例名调用,实例方法只能实例名调用。

从对象属性找,没有的话,找类里的

实例方法和类方法的区别:
定义方式不同、调用方式不同、权限不同
调用方式不同

①实例方法:只能用类的实例(对象)来调用,第一个参数总是 self ,调用时由 python (默认)自动传入当前调用该方法的实例。
②类方法:@ classmethod 修饰,默认认 cls 参数作为第1个参数,可以用类直解调用,也可实例调用,但类方法不能访问对象属性(self.***)、只能访问类属性。

权限不同:

实例权限高于类权限(所有人能做,则张3能做;张3能做,并不是所有人能做)

实例可以直接访问类属性和实例属性、实例方法、可以调用类方法

成员可见性:

左单下划线表示被保护,只有自己(本类)和子类可见

左双下划线表示私有,只有自己可见

左右双下划线是内置的默认方法,都有特殊作用

class Person:
 #类属性,所有成员共享,定义在类中,方法外的变量
  height = 180
  name = "小明"
  count = 0

  def __init__(self,name,height):#name,height是方法的参数,是局部变量,作用域是整个__init__方法
    #实例属性self.height = height, 将局部变量height赋值给实例属性self.height
    #防止外部通过person.height篡改,故写成私有属性,读取的话,可以通过实例._类名__属性/方法读取,但不建议使用,所以换成定义get方法,修改的话定义set方法,,或者使用@propert装饰器变成属性
    self.__height = height
    self.__name = name
    __class__.count += 1
    print("我是第" + str(__class__.count) + "实例,我叫" + self.name)

  def say(self):#定义在类中的函数,称为实例方法,自带self参数
    print(f'I am: {self.name}')
    return 'haha'

  #获取私有属性的值
  @property
  def height(self):
    return self.__height

  def getHeight(self):
    return self.__height
    
  #修改私有属性的值
  @height
  def height(self,height):
  	self.__height = heght
  	
  def setHeight(self,height):
    #检查入口参数的合法性
    self.__height = height

    
  @staticmethod
  def height():
  	print('这是一个静态方法,不能调用实例属性和实例方法)

  @classmethod
  def classCount(cls):
    print("一共实例了" + str(cls.count) + "个Person对象")
    print('这是一个动态方法,不能调用实例属性和实例方法)
#
#Person.classSay()
person = Person('小米',189)
person.setHeight(175)
print(person.getHeight())
print(person.height)

#AttributeError: 'Person' object has no attribute '__height'
#print(person.__height)



什么时候定义类方法?实例方法?

—跟具体的某个实例没有关系的方法,一般来说我们定义成类方法,由类名直接词用。
—跟具体的某个实例有关,每个实例可能拥有不一样的方法,一般来说我们会定义成实例方法,由实例来进行访问
属性方法:可以像属性一样进行调用的方法(防止直接对属性的值进行修改)

魔法方法和特殊函数

obj.dict 对象的属性字典

obj.__class__对象所属的类

class.__bases__类的父类元组

class.__base__类的父类 若有多个父类,则输出最先继承的父类

class.__mro__类的层次结构 如:C类继承了A类,B类,object类

class.subclass()类的子类列表

_module

面向对象代码实现:
class Cat:
  '''
  这是猫的类
  '''
  def __init__(self,name,tail_length=10):
    self.name = name
    self.__privatename = name
    self.taillen = tail_length
    print("我是一只猫,我叫%s"%self.name)

  def __del__(self):
    print("我被系统回收了")

  def __call__(self,*args,**kwargs):
    #类的对象被调用,执行
    print(args[0]+args[1])

  def __str__(self):
    return '我是%s'%self.name

  def __len__(self):
    return self.taillen

  def __iter__(self):
    return iter([1,2,3,4])

  def __getitem__(self, key):
    if key == 'name':
      return self.name
    else:
      return None

  def __setitem__(self, key, value):
    if key == 'name':
      self.name = value

  def __delitem__(self, key):
    if key == 'name':
      del self.name
  #可以进行数学运算加add 减sub 乘mul 除div 幂pow 余mod 比较lt、gt、eq、le、gt、ne、
  def __add__(self, other):
    if isinstance(other,Cat):
      return [self,other]
    elif isinstance(other,list):
      other.append(self)
      return other

cat = Cat('hao',15)
print(callable(cat))
# #__del__析构函数
print(cat)
#del cat
print(cat)
print(cat.__doc__)
print(cat.__dict__)
print(cat._Cat__privatename)
print(cat.__class__)
print(cat.__module__)
print(len(cat))
for i in cat:
  print('cat',i)


cat1 = Cat('33')
cat2 = Cat('44')
print(cat1 + cat2)
cats = cat1 + cat2
cat3 =Cat('alen')
print(cat3 + cats)

print(cat['name'])
cat['name'] = 'li'
print(cat['name'])
# del cat['name']
# print(cat['name'])
实例化后,再动态赋值属性
class Person:
 #类属性,所有成员共享
  height = 180

  def __init__(self):
    pass

  def say(self):
   print("I am speaking")
   return 'haha'

person = Person()

#person2 = Person()
#person.height = 175
#person2.height = 179
print(person.height)
print(person2.height)
print(Person.height)
print(person.__dict__)
print(person2.__dict__)
print(Person.__dict__)
__dict__显示类包含的属性
若对象没有该属性,则往类找
175
179
180
#{}
#{}
{'height': 175}   
{'height': 179}   
{'__module__': '__main__', 'height': 180, '__init__': <function Person.__init__ at 0x00000292B43B2EA0>, 'say': <function Person.say at 0x00000292B43B2F28>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}
在实例化时传入实例属性
class Person:
  # 类属性,所有成员共享
  height = 180
  name = "小明"

  def __init__(self, height, name):
    # 实例属性
    self.height = height
    self.name = name

  def say(self):
    print("I am" + self.name)
    return 'haha'

  @classmethod
  def classSay(cls):
    print("I am" + cls.name)


person = Person(185, '小宝')
Person.classSay()
print(person.height)
print(Person.height)
print(person.__dict__)
print(Person.__dict__)
使用类属性和类方法场景
class Person:
 #类属性,所有成员共享
  height = 180
  name = "小明"
  count = 0

  def __init__(self,name,height):
    #实例属性
    self.height = height
    self.name = name
    Person.count += 1
    print("我是第" + str(Person.count) + "实例,我叫" + self.name)

  def say(self):
   print("I am" + self.name)
   return 'haha'

  @classmethod
  def classCount(cls):
    print("一共实例了" + str(cls.count) + "个Person对象")

person1 = Person('小米',189)
person1 = Person('小侯',199)
Person.classCount()
#用__class__.count代替Person.count

继承(子类继承父类,可以有N个父类,若没继承类,默认继承oject)
class RichMan:
  def __init__(self,money,company):
    self.money = money
    self.company = company
    
#需要导入父类模块中的RichMan类   ...
class RichChild(RichMan):
  def __init__(self,money,company,mount):
    super().__init__(money,company)
    self.mount = mount
    #子类与父类同名,先调用父类的init,确保父类初始化成功,但要是方法名与父类相同,则会直接覆盖
    self.ownMoney = 0
object所有类直接或间接的父类

所有类都拥有object类的属性和方法

特殊方法:

new:由系统调用,用于创建对象(先__new__,再__init__)

init:

str:对象的描述,返回值是str类型,默认输出对象的内存地址

多态

指的就是"多种形态",即便不知道一个变量所引用的对象到底是什么类型,仍然可以通过这个变量调用对象的方法。
在程序运行过程中根据变量所引用对象的数据类型,动态决定调用哪个对象中的方法。
Python 语言中的多态,根本不关心对象的数据类型,也不关心类之间是否存在继承关系,只关心对象的行为(方法)。只要不同的类中有同名的方法,即可实现多态

class Person():
	def __init__(self,money,company):
    	self.money = money
    	self.company = company
    
	def eat(self):
  		print('人吃五谷杂粮')
  	
 class Cat():
 	def eat(self):
  		print('猫喜欢吃鱼')
  		
  def fun(obj): #obj是函数的形式参数,在定义时不知道数据类型
  	obj.eat() #通过变量obj(对象)调用eat方法
  	
  person = Person()
  cat = Cat()
  
  fun(person) #Python 语言中的多态,根本不关心对象的数据类型,,只关心对象的行为(方法)
  fun(ct)
  
深拷贝、浅拷贝

变量的赋值:只是形成两个变量,实际上还是指向同一个对象

浅拷贝:copy.copy(),拷贝时,对象包含的子对象内容不拷贝

深拷贝:copy.deepcopy(),源对象和拷贝对象的子对象也不相同

import copy

class CPU():
	pass
	
class Disk():
	pass
	
class Computer():
	def __init__(self):
	
cpu = CPU()
disk = Disk()
com = Computer(cou,disk)
com1 = com
com2 = copy.copy(com)
print(com1,'子对象的内存地址:',com1.cpu,com1.disk)
com3 = copy.deepcopy(com)
	

 
推导式

针对序列:列表、元组、字符串

res1 = [x**2 for x in range(1,11)]

res2 = [x**2 for x in range(1,11) if x%2 == 0]

res3 = [x**2 for x in range(1,11) if x**2 %2 == 0]
#多重循环 + 判断
res5 = [x+y for x in 'python' for y in '123' if x+y != 'y1']
print(res5)
print(res1)
print(res2)
print(res3)
res4 = tuple(x**2 for x in range(1,11))
dic = {x:x**2 for x in range(1,11)}
ss = {x for x in range(1,11)}
print(res4)
print(dic)
print(ss)
模块module :一个包含所有你定义的函数和变量(.py)

导入:

1、import module

2、from module import funcname /*

包Package

1、from 包名.模块名 import 函数/变量

2、import 包名.模块名

3、from 包名 import 模块名 as 别名

主程序运行
if __name__ == '__main__':
	pass

name__属性是每个 py 文件的一个内置属性,当这个文件是被直接执行时.值为__main;若作为包被导入,则值会变成文件名。

所以可以利用它来判断当前文件的使用方式,从而执行特定的代码。

场景:模块中写好函数和变量后,是需要进行调试的.为了避免导入时会执行调试,使用该方法。

Python的异常处理语法(异常捕获)
try:
  程序执行语句块
except Exception as e:
   异常处理语句块
else:
  无异常时执行的语句块
finally:
  最后执行的语句块
raise 主动抛出异常
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值