Python学习笔记 9

python面向对象变成进阶篇

1. 类成员之–字段

字段类型:普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同,

  • 普通字段属于对象,每创建一个实例就会在内存中保存一个
  • 静态字段属于类,类在初始化的时候就创建了,无论后来创建了多少个实例,在内存中只有一份

字段的调用:静态字段可以通过对象或者类进行访问,但是普通字段只能通过对象进行调用访问

1.1 一般静态字段用法示例:

class Province(object):
    country = 'china'#可以通过实例的id来感受,所有实例的country属性id都是相同的
    def __init__(self,name):
        self.name = name

    def showProvince(self):
        print self.name,self.country

p = Province('Qinghai')
print p.country
\# 通过实例访问静态字段

print Province.country
\# 通过类直接访问静态字段

应用场景: 通过类创建对象时,如果每个对象都具有相同的字段,那么就使用静态字段,内存占用就会降低

1.2 私有静态字段:
__private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中调用: self.__private_attrs。

class Province(object):
    __country = 'china'
    def __init__(self,name):
        self.name = name

    def showProvince(self):
        print self.name,self.__country

p = Province('Qinghai')
#print p.__country 或者 #print p.country
#上边调用会报错,因为私有字段不能在类的外部通过实例被访问
p.showProvince()
#可以通过方法来显示类的私有属性,且只能通过方法显示!!!
#print Province.__country 或者 #print Province.country
#上边调用会报错,因为私有字段不能在类的外部通过类来进行访问

print pq._Province__country
#强制访问私有字段

如果想要强制访问私有字段,可以通过 【对象.类名_私有字段明 】访问(如:obj._C__foo),不建议强制访问私有成员。

2. 类成员之–方法

类成员方法包括:普通方法、静态方法和类方法,三种方法在内存中都归属于类,区别在于调用方式不同。

普通方法:由对象调用;至少一个self参数;执行普通方法时,自动将调用该方法的对象赋值给self;
类方法:由类调用; 至少一个cls参数;执行类方法时,自动将调用该方法的类复制给cls;
静态方法:由类调用;无默认参数;

类方法:

class DateTest(object):
    def __init__(self,year,month,day):
        self.year = year
        self.month = month
        self.day = day

    def show(self):
        return 'year:{} \nmonth:{}\nday:{}'.format(self.year,self.month,self.day)


    @classmethod
    #类方法的格式,一个装饰器
    def get_str_date(cls,s):
        yeara, montha, daya= map(int, s.split('-'))
        dateout = cls(yeara,montha,daya)
        return dateout
d = DateTest.get_str_date('2017-09-05')
print d.show()

静态方法:

class DateTest(object):
    def __init__(self,year,month,day):
        self.year = year
        self.month = month
        self.day = day

    def show(self):
        return 'year:{} \nmonth:{}\nday:{}'.format(self.year,self.month,self.day)


    @classmethod
    def get_str_date(cls,s):
        if cls.is_valid_date(s):
            yeara, montha, daya= map(int, s.split('-'))
            dateout = cls(yeara,montha,daya)
            return dateout
        raise Exception("Invalid date!")

    @staticmethod
    #静态方法的格式,也是一个装饰器
    def is_valid_date(s):
        yeara, montha, daya = map(int, s.split('-'))
        return yeara >=1970 and  1<=montha<=12 and 1<=daya<=31
try:
    d = DateTest.get_str_date('2017-19-05')
    print d.show()
except:
    print 'Failed to create date!'

相同点:对于所有的方法而言,均属于类(非对象)中,所以,在内存中也只保存一份。

不同点:方法调用者不同、调用方法时自动传入的参数不同。

3. 类成员之–属性

Python中的属性其实是普通方法的变种。

由属性的定义和调用要注意一下几点:

定义时,在普通方法的基础上添加 @property 装饰器;
定义时,属性仅有一个self参数
调用时,无需括号
方法:foo_obj.func()
属性:foo_obj.prop

注意:属性存在意义是:访问属性时可以制造出和访问字段完全相同的假象

属性由方法变种而来,如果Python中没有属性,方法完全可以代替其功能。

实例:对于主机列表页面,每次请求不可能把数据库中的所有内容都显示到页面上,而是通过分页的功能局部显示,所以在向数据库中请求数据时就要显示的指定获取从第m条到第n条的所有数据(即:limit m,n),这个分页的功能包括:

根据用户请求的当前页和总数据条数计算出 m 和 n
根据m 和 n 去数据库中请求数据

Python的属性的功能是:属性内部进行一系列的逻辑计算,最终将计算结果返回。

class Pager:
    def __init__(self, current_page):
        # 用户当前请求的页码(第一页、第二页...)
        self.current_page = current_page
        # 每页默认显示10条数据
        self.per_items = 10

    @property
    def start(self):
        val = (self.current_page - 1) * self.per_items
        return val

    @property
    def end(self):
        val = self.current_page * self.per_items
        return val

p = Pager(1)
print p.start,p.end
#根据传入的当前页数,然后返回下一次的起始页
#1 10
p1 = Pager(2)
print p1.start,p1.end
#10 20

注:经典类中的属性只有一种访问方式,其对应被 @property 修饰的方法
新式类中的属性有三种访问方式,并分别对应了三个被@property、@方法名.setter、@方法名.deleter修饰的方法

由于新式类中具有三种访问方式,我们可以根据他们几个属性的访问特点,分别将三个方法定义为对同一个属性:获取、修改、删除

4. 类的特殊成员 __str__

如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。

如果没有定义__str__方法的话则输出类型以及内存地址

class Halo:

    def __str__(self):
        return 'lockey'

obj = Foo()

print obj

输出:lockey

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值