前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python基础七

python基础七

作者头像
不断折腾
发布2019-09-23 10:34:48
3980
发布2019-09-23 10:34:48
举报

无论是风里,还是在雨里,我都在这里守候着你~

对于封装更正

私有方法,和私有属性,静态私有属性

class Person:

__person = '人类'

def __init__(self,name,age):

self.name = name

self.__age = age

def get_age(self):

return self.__age

def set_age(self,newage):

if newage>15:

self.__age = newage

else:

print('年龄需要大于15')

zhangsan = Person('张三',18)

# print(zhangsan.__age) #这样是调用不到这个属性的

print(zhangsan.get_age()) # 这样才是正确的调用方式

__person表示静态私有属性,在外部同样获取不到。在属性前加上__表示封装变成私有属性,在外部是不能调用的。只能在内部使用,我们再在Person中添加一个方法,用这个方法获取就可以了。

set_age:我们如果想要修改,如果想要对age有一个约束条件就可以这样写。

同样,我们在Person中的方法名加上一个__,就变成了私有方法,外部无法调用。在子类中也无法去调用。

将调用方法看上去像调用一个属性

class Person:

def __init__(self,name):

self.__name = name

@property

def get_name(self):

return self.__name

p = Person('张三')

print(p.get_name)

@property:内置装饰器,实现如上效果。

但是get_name不能去传参数,如果我想要去修改呢?

如下:

class Person:

def __init__(self,name):

self.__name = name

@property

def get_name(self):

return self.__name

@get_name.setter

def get_name(self,newname):

self.__name = newname

p = Person('张三')

print(p.get_name)

p.get_name = '李四'

print(p.get_name)

把get_name 当成属性去修改它即可。

删除一个属性:

class Person:

def __init__(self,name):

self.__name = name

@property

def get_name(self):

return self.__name

p = Person('张三')

print(p.get_name)

del p.get_name

会被错,会提示can't delete attribute,不能删除。

那怎么样才能删除呢:

class Person:

def __init__(self,name):

self.__name = name

@property

def get_name(self):

return self.__name

@get_name.deleter

def get_name(self):

print('删除我')

p = Person('张三')

print(p.get_name)

del p.get_name

print(p.get_name)

执行会输出:

张三

删除我

张三

显然,没有报错,但是却没有删除,但是其中执行了删除我这个方法,也就是说我们在外面del一个属性(方法)实际上是调用了这个方法,那么我们将输出删除我这个方法修改成:

@get_name.deleter

def get_name(self):

del self.__name

即可。 第二次输出会报错:没有这个属性。

其他:

1、判断一个类是不是另一个类的子类:

class A:

pass

class B(A):

pass

print(issubclass(B,A)) # True

是返回True,不是返回False

2、判断一个对象是否是一个类的对象

class A:pass

a = A()

print(isinstance(a,A)) # True

是返回True ,不是返回False

定义类的规范

当我们想要定义一个类的规范的时候,比如支付宝和卫星都有支付功能,我想写一个方法,可以调用支付宝和微信的支付功能。

class Wechat:

def pay(self,money):

print('微信支付了%s元'%money)

class Alipay:

def pay(self,money):

print('阿里支付了%s元'%money)

def payzhifu(pay_nei,money):

pay_nei.pay(money)

wechat = Wechat()

p = payzhifu(wechat,100)

输出:微信支付了100元

看来是没有毛病的,但是如果再来一个百度支付,而百度的支付方法不是pay,那样就会报错,

所以我们需要写一个类的规范。让支付类都必须有pay方法。

这样:

from abc import abstractmethod,ABCMeta

class PayAncestors(metaclass = ABCMeta):

@abstractmethod

def pay(self,money):

pass

class Wechat(PayAncestors):

def pay(self,money):

print('微信支付了%s元'%money)

class Alipay(PayAncestors):

def pay(self,money):

print('阿里支付了%s元'%money)

def payzhifu(pay_nei,money):

pay_nei.pay(money)

wechat = Wechat()

p = payzhifu(wechat,100)

metaclass:指定元类

@abstractmethod:给他一个装饰器,表示要写一个类的规范了。

这样就定义了一个规范,他的子类都必须有pay方法,如果没有,就会报错,并提醒没有pay方法。

报错提示:Can't instantiate abstract class Wechat with abstract methods pay

我们称它为接口类。(在python中实际是没有接口类一说,在别的语言中有,python也可以实现,但是在python里没有接口类一说。只是模拟了接口类)他也可以叫做抽象类。(在python类中有抽象类,实实在在存在)

接口隔离原则:我们在定义以一个规范的时候,不要使用单一的总接口,也就是说,一个类中不要有多个方法,单一点。

总结:无论是抽象类还是接口类,都是面向对象的开发规范,并且都不能实例化,一般都是单继承,由于java中没有多继承,所以接口类是从java中引来的,java利用创捷接口来规范多继承。python中不存在接口类一说,只是在python中模拟了一下写法,但是在python中有抽象类,写法和上面是一样的

类方法

class Person:

__person = '人类'

def __init__(self,name):

self.name = name

def get_person(self,newperson):

Person.__person = newperson

return Person.__person

zhangsan = Person('张三')

print(zhangsan.get_person('动物类'))

如上我们可以发现,当把静态属性改为私有,修改的时候我们大概会这样写,每次都需要需要Person.xxx来调用和修改,这样就出来了一个类方法,也就是将self替换成自己这个类对象。于是修改成:

class Person:

__person = '人类'

def __init__(self,name):

self.name = name

@classmethod

def get_person(cls,newperson):

cls.__person = newperson

return Person.__person

zhangsan = Person('张三')

print(zhangsan.get_person('动物类'))

@classmethod:加一个装饰器表示类方法,不需要去实例化了。

cls:代表这个类本身。

当我们只修改,只需要静态属性的时候我们就需要这样做。

静态方法

当我们类中的方法没有用到类中的参数时候,我们可以不需要实例化类,来直接调用。

实例:

class Person:

def __init__(self,name,age)

self.name =name

self.age = age

@staticmethod

def getwrite():

name = input('name:')

age = input('age:')

Person(name,age)

在以前,我们调用需要先这样:

p = Person('张三'.18)

但是现在我们用@staticmethod声明他是一个静态方法之后,我们只需要这样:

Person.getwrite()即可。

让我们没有用到类中的任何参数,就可以这样定义。

反射

以字符串的形式去获取变量并操作。和eval相似,但是比eval强大。

class Person:

list = ['星期一','星期二','星期三','星期四']

def fun_one(self):

print('我是第一个方法')

def fun_two(self):

print('我是第二个方法')

如果我们想要拿到list列表,可以这样:

li = getattr(Person,'list')

输出:['星期一', '星期二', '星期三', '星期四']

直接输出一个列表。假如在Person中没有这个list那不就会报错了?是的

所以:

if hasattr(Person,'list'):

li = getattr(Person,'list')

hasattr():如果存在会返回True,否则返回False。二者搭配使用即可。

如果想要调用方法:同样的使用方式,但是获取到的只是一个内存地址,需要加上括号后执行

class Person:

list = ['星期一','星期二','星期三','星期四']

def fun_one(self):

print('我是第一个方法')

def fun_two(self):

print('我是第二个方法')

p = Person()

func = getattr(p,'fun_one')

func()

反射模块属性

getattr(模块名,'属性名')

反射模块方法

ret = getattr(模块名,'方法名')

ret()

总结:什么是可以反射的?

凡是xxx.qqq格式能获取到的的都可以,xxx写在getattr()方法的第一个参数,qqq写在getattr()的第二个参数。

反射当前页面的值:

import sys

name = '张三'

print(getattr(sys.modules[__name__],'name'))即可。

方法也就大同小异了。

反射修改

class A:

pass

a = A()

setattr(a,'name','张三')

反射删除变量

class A:

name = 'lisi'

delattr(A,name)

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-11-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 python入门到放弃 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档