属性分为实例属性与类属性
方法分为普通方法,类方法,静态方法
一:属性:
尽量把需要用户传入的属性作为实例属性,而把同类都一样的属性作为类属性。实例属性在每创造一个实例时都会初始化一遍,不同的实例的实例属性可能不同,不同实例的类属性都相同。从而减少内存。
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()