jsp是否可以做网站,互联网公司 哪个部门负责网站建设,做小程序好还是做微网站好,资讯是做网站还是公众号欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起学习和分享Linux、C、C、Python、Matlab#xff0c;机器人运动控制、多机器人协作#xff0c;智能优化算法#xff0c;滤波估计、多传感器信息融合#xff0c;机器学习#xff0c;人工智能等相关领域的知识和… 欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起学习和分享Linux、C、C、Python、Matlab机器人运动控制、多机器人协作智能优化算法滤波估计、多传感器信息融合机器学习人工智能等相关领域的知识和技术。 python面向对象 | 类和对象 三大编程范式类的属性类和实例对象对象和实例属性类和实例的作用域静态与组合静态属性类方法静态方法组合 专栏《python从入门到实战》 三大编程范式
三大编程范式是指面向过程编程、函数式编程和面向对象编程。三种编程范式只是习惯不同但是并没有高低之分。正如那句话所说天下武功门派没有高低之分只有习武之人的高低之分。 我们都知道C语言是面向过程的C是面向对象的。但是并不是说C语言一定就只能面向过程我们用C也可以实现面向对象实际上在Linux内核中就有很多面向对象的思想而C也可以面向过程编程只能说C提供了一些特性可以更好地支持面向对象。总之三大编程范式没有高低之分也没有和具体的语言绑定这一说。 需要注意的是函数式编程 ≠ 用函数编程 函数式编程就是用python内的函数来表达出数学层面的函数二者结合就是函数式编程即数学函数python函数。 编程最开始是无组织无结构的从简单的控制流中按步骤写指令从指令中提取出重复的代码块或逻辑组织到一起便实现了代码复用这也标志着代码由无结构走向了结构化写程序的过程也具有了逻辑性。如果我们定义函数并在函数外定义变量将变量以参数的形式传递给函数这就实现了数据与动作的分离如果更进一步我们把数据和动作内嵌到一个结构里面那我们就有了一个对象系统。也就是说对象是数据和函数的结合物。 注意类和对象是有区别的类是抽象的概念抽象出共同属性和方法对象是一个实例是类实例化出来的对象。面向对象编程并不等于面向类编程函数和类都可以实现面向对象编程。 下面是一个用函数实现面向对象的例子
def city(name, addr, type):def init(name, addr, type):c {name:name,addr:addr,type:type,visit:visit,}return cdef visit(c):print(%s %s %s 欢迎您 %(c[addr], c[type], c[name]))return init(name, addr, type)c1 city(济南, 山东, 省会)类的属性
声明一个类和声明一个函数很相似我们使用函数实现面向对象程序设计的时候是通过返回值得到具体对象的同样class()也表示执行这个类也是实例化的过程和函数一样它会返回一个对象。 注意python2分为经典类和新式类python3统一都是新式类。
class c1:‘经典类’pass
class c2(parent_class):‘新式类’pass类的属性有两种数据属性和函数属性。 数据属性变量实例对象只有数据属性。 函数属性方法即函数。
print(classname) #打印类的属性 – 属性名列表
print(classname.__dict__) #查看类的属性字典 – 属性的键值对
print(classname.__dict__[‘attrname’]) #获取某一个属性
classname.__dict__[‘funcname’]() #运行类的某一个属方法python为类内置的特殊属性
类名.__name__# 类的名字(字符串)
类名.__doc__# 类的文档字符串
类名.__base__# 类的第一个父类 – python中所有类都有一个共同父类
类名.__bases__# 类所有父类构成的元组
类名.__dict__# 类的字典属性
类名.__module__# 类定义所在的模块
类名.__class__# 实例对应的类(仅新式类中)类和实例对象
类的作用域和函数一样调用类的属性时会先在自己作用域寻找自己作用域找不到再去上一层作用域寻找。 实例只有数据属性但是实例对象可以调用类的数据属性。 实际上实例就是用通过类的__init__产生的它只包含__init__方法内的一些属性。 实例没有方法属性但是实例可以调用类的方法属性注意调用的方法是类的而不是实例自己的。 如果想调用类的方法需要通过类去调用实例对象无法调用类的方法因为不在作用域内并把实例作为参数传给classname.function(obj)。 类中的方法一般都要设置一个参数self当使用实例调用类的方法时默认会把实例对象本身传给self。实例调用方法会自动传参self但是类调用方法需要手动传入实例参数。 实例是由类中的__init__方法产生的由__init__传参并返回的对象实力只含有__init__内的数据属性但是实例可以访问类的数据属性__init__外部的因为实例的作用域也就是__init__的作用域在类的作用域之内可以访问上一层作用域的变量但是实例是没有方法属性的实例想调用方法只能去找类要并把自己传过去。类中的方法都有一个默认参数在第一个位置也就是self它用于指向实例自己。 可以对类的数据属性和方法属性进行增删改查 对实例的数据属性也可以增删改查也可以对实例增加方法属性调用的时候相当于调用实例自己的方法需要手动把实例自己不传自己也行实际上传啥都可以传进去赋给self实例调用类的方法时是自动传参给self的传的是自己。- 但是不要给实例增加方法应该把实例的数据属性和方法分离同一个类创建的实例调用的都是类的方法这样数据和方法就分离了。
对象和实例属性
实际上实例化就是类名()的过程其返回结果是一个对象加上括号的行为和函数的运行非常相似。类和函数一样有作用域我们可以把类看作是最外层的函数也就是最大的作用域。实例化会自动触发init函数的运行最后返回一个值也就是实例我们需要的实例属性就存放在init函数的局部作用域里。类有类的属性字典即类的作用域而实例有实例的属性字典即实例的作用域。也就是说当我们使用对象的方法时obj.func()会先在自己的作用域找找不到再去外层类的字典中去找都找不到才会报错。
类和实例的作用域
#---------------------------------------------------------
class People:name ‘su’def __init__(self, age): #通过自动运行__init__进行实例化self.age age #实例的作用域在__init__内def test(self, string)print(‘test %s’ %string)p1 People(‘18’)
p1.name ‘yy’
#相当于在实例的字典中增加一个属性和类的字典毫无关系
print(People.name) # su
print(p1.name) #yy#---------------------------------------------------------name ‘su’
class People:def __init__(self, age): self.age age def test(self, string)print(‘test %s’ %string)
p1 People(‘18’)
print(p1.name) #err – 只会在类的作用域内部找#---------------------------------------------------------class People:def __init__(self): #__init__除了不能返回值和普通函数无区别age input(‘input age’) self.age age def test(self, string)print(‘test %s’ %string)
#千万不要这样做#---------------------------------------------------------name ‘su’
class People:def __init__(self, age): self.age age print(‘name: --’, name) #可以打印出def test(self, string)print(‘test %s’ %string)
p1 People(‘18’)
#只有以点.去访问的时候才遵循在类的内部去找的原则因为.是成员运算符#---------------------------------------------------------name ‘su’
class People:name ‘tt’def __init__(self, age): self.age age print(‘name: --’, name) #sudef test(self, string)print(‘test %s’ %string)
p1 People(‘18’)
print(People.name)
print(p1.name)
# .调用方式在类内部寻找遵循类的作用域在类和实例的字典中去找
#不用.访问那么就和类还有实例没关系就是访问普通变量它就不会在类还有实例的字典内找变量而是查找普通变量#---------------------------------------------------------class People:name ‘tt’l [‘a’, ‘b’]def __init__(self, age): self.age age def test(self, string)print(‘test %s’ %string)
p1 People(‘18’)
print(p1, l)
p1.l [1, 2, 3] #改的是实例在实例的字典中加了一个列表
#给实例新增加了一个新属性 表示新增
print(People.l)
print(p1.l)
p1.l.append(‘c’) #这里没有用等号所以不会给实例p1增加新属性
#这就是改的类的属性了
print(p1.__dict__) #实例的属性字典
print(People__dict__) #类的属性字典
静态与组合
静态属性
property - 装饰器
class People:def __init__(self, name, age): self.name name self.age ageproperty def get_attr(self):#print(‘%s - %s’ %( self.name, self.age))return [name, age]
p1 People(‘su’, 17)
p1.get_attr #调用的时候不再加()就可以执行
#调用方法属性和调用数据属性一样这样就隐藏了背后的实现逻辑
#调用者调用的时候只能看到结果但是无法得知背后的逻辑实现
#把方法属性封装起来像数据属性一样类方法
classmethod
class People:tag 1def __init__(self, name, age): self.name name self.age ageproperty def get_attr(self):#print(‘%s - %s’ %(self.name, self.age))return [name, age]def get_tag(self):print(‘%s’ %self.tag)
People.get_tag(x) #原则上可以传入任何参数但是底层self.tag限制了必须传入一个实例
p1 People(‘su’, 17)
People.get_tag(p1)
#我的需求是只打印类的方法我不想和实例捆绑在一块
class People:tag 1def __init__(self, name, age): self.name name self.age ageproperty def get_attr(self):#print(‘%s - %s’ %(self.name, self.age))return [name, age]classmethoddef get_tag(cls): #参数是一个类名print(‘%s’ %cls.tag)
People.get_tag() #将类和实例分离 – 提供了由类调用的方法 – 类方法
#类方法也会自动传参会把调用的类名自动传入给cls
#类方法只能调用类属性不能调用实例属性实例属性是由self调用的
#只要参数带self那么这个方法就和实例绑定了
#cls就是和类绑定
#实例也能调用类方法 – 但是最好不要这样做类方法出现的意义就是给类调用静态方法
staticmethod
class People:def __init__(self, name, age): self.name name self.age ageproperty def get_attr(self):print(‘%s - %s’ %(self.name, self.age))staticmethod #类的工具包def do_thing(a, b, c):print(a, b, c)def do_thing2(a, b, c):print(a, b, c)print(People.__dict__)
p1 People(‘su’, 17)
print(p1.__dict__)
People.do_thing(1, 2, 3) #ok – 不会自动传参
p1.do_thing(1, 2, 3) #ok – 不会自动传参
People.do_thing2(1, 2, 3) #ok
p1.do_thing2(1, 2, 3) #error #p1会自动把自己传进去 – 参数错误# property – 将方法和实例绑定 – 用self调用实例属性 – 自动传入实例本身给self
# classmethod – 将方法和类绑定和实例就没关系了- 用cls调用类的属性 – 自动传入本身给cls
# staticmethod – 既不和实例绑定也不和类绑定和实例和类都没关系了是一个类的工具包 – 不会自动传参
# 静态方法staticmethod只是名义上归属类管理不能使用类变量和实例变量是类的工具包 – 既没有self也没有cls无法通过.去调用属性组合
组合是做关联的类与类之间没有共同点但是它们之间是有关联的这时就用组合去解决去建立关联。实例对象做参数类做参数 这里面的Head()、Foot()等就是一个对象类名加()本身就是实例化的意思所以上面的效果和直接传递一个实例对象的参数效果是一致的。