python中一切皆对象
在Python中函数和类也是对象,属于Python的一等公民
1. 可以赋值给一个变量
# 函数可以被赋值给变量
def hello(name='world'):
print('hello ' + name)
my_func = hello
my_func('python')
# 类可以被赋值给变量
class Person:
def __init__(self):
print('__init__')
my_class = Person
my_class()
2.可以添加到集合对象中
# 定义集合对象
obj_list = []
# 添加方法与类到几个中
obj_list.append(hello)
obj_list.append(Person)
for item in obj_list:
print(item())
输出结果 hello word
None
__init__
<__main__.Person object at 0x106cf7940>
3.可以作为参数传递给函数
# 输出类型
def print_type(item):
print(type(item))
for item in obj_list:
print_type(item)
输出结果 <class 'function'>
<class 'type'>
4.可以当做函数返回值
def decorator_func():
print('调用decorator_func函数')
return hello
my_func = decorator_func()
my_func('python')
输出结果 调用decorator_func函数
hello python
type object class 之间的关系
代码实例
a = 1
type ( 1 )
#Out[3]: int
#type(int)
#Out[4]: type
说明:
由上面的代码可以知道,type生成了int,int生成1
因此是由type生成了类对象,再有类对象生成了实例
type->class->obj
class Student :
pass
class MyStudent ( Student ):
pass
#MyStudent.__bases__
# Out[10]: (__main__.Student,)
# Student.__bases__
# Out[11]: (object,)
说明:由上面的代码我们可以看出bject是最顶层的基类
type 是一个特殊且重要的对象,type既是一个类,也是一个对象,type的基类是object,object又是由type生成的,
所以最上方的图就刚好描述了整个流程
Python中的内置类型
• None(全局只有一个)
• 数值
• 迭代类型
• 序列类型
• 映射(dict)
• 集合
• 上下文管理类型(with)
• 其他
魔法函数
1、__init__():
所有类的超类object,有一个默认包含pass的__init__()实现,这个函数会在对象初始化的时候调用,我们可以选择实现,也可以选择不实现,
一般建议是实现的,不实现对象属性就不会被初始化,虽然我们仍然可以对其进行赋值,但是它已经成了隐式的了,编程时显示远比隐式的更好
2、__str__():
直接打印对象的实现方法,__str__是被print函数调用的,一般都是return一个什么东西,这个东西应该是以字符串的形式表现的,
如果不是要用str()函数转换,我们可以直接print的对象都是实现了__str__这个方法的,比如dict。
3、__new__():
在object类中存在一个静态的__new__(cls, *args, **kwargs)方法,该方法需要传递一个参数cls,cls表示需要实例化的类,此参数在实例化时由Python解释器自动提供,__new__方法必须有返回值,
且返回的是被实例化的实例,只有在该实例返回后才会调用__init__来进行初始化,初始化所用的实例就是__new__返回的结果,也就可以认为是self,
4、__unicode__():
__unicode__()方法是在一个对象上调用unicode()时被调用的。因为Django的数据库后端会返回Unicode字符串给model属性,所以我们通常会给自己的model写一个__unicode__()方法。
如果定义了__unicode__()方法但是没有定义__str__()方法,Django会自动提供一个__str__()方法调用 __unicode__()方法,然后把结果转换为UTF-8编码的字符串对象,所以在一般情况下,
只定义__unicode__()方法,让 Django来处理字符串对象的转换,
5、__len__():
len调用后会调用对象的__len__函数,一般用来计算可迭代对象的长度
以上是整理的一小部分常用魔法函数,魔法函数不受类的约束,并不是一定要实现的方法。
详细魔法函数介绍
鸭子类型和多态
鸭子类型:
当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来像鸭子、叫起来也像鸭子、那么这只鸟就可以被称为鸭子
class Cat ( object ):
@ staticmethod
def say ():
print ( 'i am cat' )
class Dog ( object ):
@ staticmethod
def say ():
print ( 'i am dog' )
class Duck ( object ):
@ staticmethod
def say ():
print ( 'i am duck' )
animal_list = [ Cat , Dog , Duck ]
for animal in animal_list :
animal (). say ()
输出结果:
i am cat
i am dog
i am duck
上述class都实现了一个名为say的方法,那么我们可以把这些的类,都归于一种类型,在python中实现多态,只需要去实现相同名称的方法就可以了,
(多态都是子类覆盖超类的方法,不同的实例访问的方法不同,都是先访问自己的,自己没有再去找超类的方法)
抽象基类
抽象基类有两个特点:
1.规定继承类必须具有抽象基类指定的方法
2.抽象基类无法实例化
抽象基类无法实例化基于上述两个特点,
抽象基类主要用于接口设计实现抽象基类可以使用内置的abc模块
代码
import abc
class Human(metaclass=abc.ABCMeta):
@abc.abstractmethod # 规定子类必须有名为introduce的实例方法
def introduce(self):
pass
@abc.abstractproperty # 规定子类必须有名为country的装饰器方法
def country(self):
pass
@abc.abstractclassmethod # 规定子类必须有名为gender的类方法
def gender(cls):
pass
@abc.abstractstaticmethod # 规定子类必须有名为hello的静态方法
def hello():
pass
class Person(Human):
__country = "China"
def __init__(self, name, age):
self.name = name
self.age = age
def introduce(self):
return "I'm {}, {}.".format(self.name, self.age)
@property
def country(self):
return Person.__country
@classmethod
def gender(cls):
return "female"
@staticmethod
def hello():
print("What the hell?")
person = Person("Li", 24)
print(person.introduce())
print(person.country)
print(Person.gender())
person.hello()
# I'm Li, 24.
# China
# female
# What the hell?
instance 和 type的区别
instance和type都是用来验证某个对象的类型的,它们的区别如下:
type()不会认为子类是一种父类类型,而instance会认为子类也是一种父类类型.
isinstance() #函数来判断一个对象是否是一个已知的类型,类似 type()。
isinstance() #与 type() 区别:
type() #不会认为子类是一种父类类型,不考虑继承关系。
isinstance() #会认为子类是一种父类类型,考虑继承关系。
#如果要判断两个类型是否相同推荐使用 isinstance()。
# 例一
a = 2
print(isinstance(a,int)) # True
print(isinstance(a,str)) # False
# type() 与 isinstance() 区别
class A:
pass
class B(A):
pass
print("isinstance",isinstance(A(),A)) # isinstance True
print("type",type(A()) == A) # type True
print('isinstance',isinstance(B(),A) ) # isinstance True
print('type',type(B()) == A) # type False
类变量和实例变量
类变量:可在类的所有实例之间共享的值(也就是说,它们不是单独分配给每个实例的)。
实例变量:实例化之后,每个实例单独拥有的变量。
class student():
age = 0
name = 'stu'
# age,name是类变量
def __init__(self,age,name):
self.age = age
self.name = name
# 访问实例变量(用self.age self.name)
student1 = student(18,'hello')
print(student1.name)
# 打印实例变量,输出hello
print(student.name)
# 打印类变量,输出stu
Python类变量被赋值
(1)类的设计里,
class里def外,通过变量名能被赋值
def里通过类对象即类名字的点运算变量名可被赋值
(2)程序里
通过类对象(类名字)的点运算类名字也可被赋值
Python实例对象变量被赋值
(1)类的设计时
def里通过self点运算变量名能被赋值,不一定非在init里,其他已被调用的方法函数里也行
(2)程序里
通过实例对象的点运算变量名可被赋值
类变量和实例变量的区别在于:类变量是所有对象共有,其中一个对象将它值改变,其他对象得到的就是改变后的结果;而实例变量则属对象私有,某一个对象将其值改变,不影响其他对象