Python_day_08_类属性

属性分为实例属性与类属性

方法分为普通方法,类方法,静态方法

一:属性:

  尽量把需要用户传入的属性作为实例属性,而把同类都一样的属性作为类属性。实例属性在每创造一个实例时都会初始化一遍,不同的实例的实例属性可能不同,不同实例的类属性都相同。从而减少内存。

  1:实例属性:

    最好在init(self,…)中初始化

    内部调用时都需要加上self.

    外部调用时用instancename.propertyname

  2:类属性:

    在init()外初始化

    在内部用classname.类属性名调用

    外部既可以用classname.类属性名又可以用instancename.类属性名来调用

  3:私有属性:

    1):单下划线_开头:只是告诉别人这是私有属性,外部依然可以访问更改

    2):双下划线__开头:外部不可通过instancename.propertyname来访问或者更改

      实际将其转化为了_classname__propertyname

二:方法

  1:普通类方法:


    def fun_name(self,...):

      pass

    外部用实例调用

  2:静态方法:@staticmethod

      不能访问实例属性!!! 参数不能传入self!!!

      与类相关但是不依赖类与实例的方法!!

  3:类方法:@classmethod

      不能访问实例属性!!! 参数必须传入cls!!!

      必须传入cls参数(即代表了此类对象—–区别——self代表实例对象),并且用此来调用类属性:cls.类属性名

  *静态方法与类方法都可以通过类或者实例来调用。其两个的特点都是不能够调用实例属性

1.特殊的类属性

class Animal(object):
    """
    Animals class
    """
    pass

print Animal.mro()
print Animal.__doc__        ##打印对象的类名
print Animal.__name__       ##打印对象名

fentiao = Animal()
print Animal.__bases__      ##打印类的所有父类 , 以元组类型返回
print fentiao.__doc__       ##打印对象的类名
print fentiao.__class__     ##打印类属性
print fentiao.__dict__      ##以字典的方式返回类的方法和属性
# 如果类不是被导入的, 显示为 __main__
# 如果类是被 import 导入的, 则显示类所在的模块名
print fentiao.__module__

**例子:
实现查看类实例化对象的个数
class Info(object):
    count = 0
    # 构造函数
    def __init__(self):
        Info.count += 1
    # 析构函数 , 在删除对象时自动调用 ;
    def __del__(self):
        Info.count -= 1
a = Info()
b = Info()
c = Info()
print Info.count
del a
print Info.count
结果为
3
2

2.类方法和静态方法

通过普通方法,类方法和静态方法,将方法封装起来,提高代码的可维护性

class Info(object):
    # 普通方法 , 第一个参数必须是 self( 对象 );
    def eat(self):
     print self
    # 类方法 , 第一个参数是 cls( 类 );
    @classmethod
    # cls 是 class 的缩写;
    def drink(cls):
        print cls
    # 静态方法 , 不需要加特殊的第一个参数 ;
    @staticmethod
    def run():
        print "run"
a = Info()
# a.eat()
a.drink()

普通方法和类方法区别
普通方法:没有@classmethod装饰器,默认第一个参数是self,调用时对象调用普通方法
类方法:  有@classmethod装饰器,默认第一个参数是class,调用时类调用类方法
静态方法: 有@staticmethod装饰器,默认第一个参数是自定义行参,调用时调用静态方法

类方法和静态方法的应用
class Date(object):
    def __init__(self,year,month,day):
        #封装类的属性
        self.year = year
        self.month = month
        self.day = day

    def echo_date(self):
        print """
        Day: %.2d
        Month: %.2d
        Year: %.4d
        """ %(self.day,self.month,self.year)

    #类方法
    @classmethod
    def str_date(cls,s):    # class --> cls --> 传递当前的类名
        year,month,day = map(int,s.split('-'))  #['2018','04','03']
        d = cls(year,month,day)
        return d

    #静态方法
    @staticmethod
    def is_date_legal(s):
        year,month,day = map(int,s.split('-'))
        return 0 < month <= 12 and 0 < day <= 31

d = Date.str_date('2018-04-03')
d.echo_date()

if Date.is_date_legal('2018-04-03'):
    print "OK"
else:
    print "NOT OK"

结果为
        Day: 03
        Month: 04
        Year: 2018

OK

3.属性property

**例子:

class Price(object):
    def __init__(self, old_price, discount):
        self.old_price = old_price
        self.discount = discount
    @property
    def price(self):
        new_price = self.old_price * self.discount
        return new_price
    @price.setter
    def price(self, value):
        self.old_price = value
    @price.deleter
    def price(self):
        print "%d is delete...." % (self.old_price)
        del self.old_price
    def __del__(self):
        print "deleteing....."
p = Price(100, 0.8)
print p.price
p.price = 200
print p.price
del p.price
# print p.price

**例子:
框架之信息分页显示
"""
@property应用
- 页面显示信息很多时,一般都会分页显示;
- 当用户选择第n页时, 显示该页需要的数据开始索引start和结束索引end;

Django:
flask:
Tornado:
"""

from django.core.paginator import  Paginator

hosts = ['172.25.254.' + str(i) for i in range(100)]

# 1:   hosts[0:10]  start= (1-1)*10  end=1*10
# 2:  hosts[10:20] start=(2-1)*10    end=2*20

class Page(object):
    # current_page: 页数
    # per_items: 每页显示的元素数;
    def __init__(self, current_page=1, per_items=10):
        self.__current_page = current_page
        self.__per_items = per_items

    @property
    def start(self):
        val = (self.__current_pagclass Student(object):
    def __init__(self, name='a', score=100):
        self.name = name
        # 在类里面, 双下划线开头的变量名称为私有属性;
        # 私有属性在该类的其他方法中可以使用;外部不能直接调用私有属性;
        # 私有属性实质是把self.__score改名为self._类名__score;
        self.__score = score

    #  # 在类里面, 双下划线开头的函数名称为私有方法;
    # 父类的私有方法, 子类不能继承;
    def __get_score(self):
        return self.__score



class MathStudent(Student):
    def __init__(self, name, score, IQ):
        super(MathStudent, self).__init__(name, score)
        self.IQ = IQ

    def ok(self):
        super(MathStudent, self).__get_score()
        print 'ok.....'



s = MathStudent('a', 'hello', 100)
print s.__get_score()e - 1) * self.__per_items
        return val

    @property
    def end(self):
        val = self.__current_page * self.__per_items
        return val

p = Page(3,5)
print hosts[p.start:p.end]

私有属性和私有方法

class Student(object):
    def __init__(self, name='a', score=100):
        self.name = name
        # 在类里面, 双下划线开头的变量名称为私有属性;
        # 私有属性在该类的其他方法中可以使用;外部不能直接调用私有属性;
        # 私有属性实质是把self.__score改名为self._类名__score;
        self.__score = score

    #  # 在类里面, 双下划线开头的函数名称为私有方法;
    # 父类的私有方法, 子类不能继承;
    def __get_score(self):
        return self.__score

class MathStudent(Student):
    def __init__(self, name, score, IQ):
        super(MathStudent, self).__init__(name, score)
        self.IQ = IQ

    def ok(self):
        super(MathStudent, self).__get_score()
        print 'ok.....'

s = MathStudent('a', 'hello', 100)
print s.__get_score()






阅读更多
文章标签: python
个人分类: linux基础
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭