创建一个英雄类:
class Hero(object):
def __init__(self, name, position):
self.name = name
self.position = position
hero = Hero("盖伦", "上单")#实例化一个英雄
print(hero.name)
私有变量、访问限制:
class Hero(object):
def __init__(self, name, position):
self.__name = name
self.__position = position
hero = Hero("盖伦", "上单")#实例化一个英雄
print(hero.name)
这时不管是用hero.name还是hero.__name都是无法访问到name的,并且会报错:AttributeError: 'Hero' object has no attribute 'name',如果外部代码要获取name和score怎么办?可以给Student类增加get_name
和get_score
这样的方法:
class Hero(object):
def __init__(self, name, position):
self.__name = name
self.__position = position
def get_name(self):
return self.__name
def get_position(self):
return self.__position
hero = Hero("盖伦", "上单")
print(hero.get_name())
要修改的话,同理在类中增加set_name等方法,并且还可以在方法中做判断、监听等操作。
在Python中,变量名类似__xxx__
的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量,所以,不能用__name__
、__score__
这样的变量名。
有些时候,你会看到以一个下划线开头的实例变量名,比如_name
,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”。
双下划线开头的实例变量是不是一定不能从外部访问呢?其实也不是。不能直接访问__name
是因为Python解释器对外把__name
变量改成了_Student__name
,所以,仍然可以通过_Student__name
来访问__name
变量。
继承:
创建一个类:
class Animal(object):
def run(self):
print("animal is running...")
创建一个类继承自Animal类:
class Dog(Animal):
pass
dog = Dog()
dog.run()
命令行得到:
想让某一个子类不继承父类某一个方法,可以在该类中增加一个该方法,当父类和子类拥有同一个方法时只会执行子类自身的。
当我们定义一个class的时候,我们实际上就定义了一种数据类型。我们定义的数据类型和Python自带的数据类型,比如str、list、dict没什么两样,判断一个变量是否是某个类型可以用isinstance()
判断,类似js中 INSTANCE instanceof Object:
>>> isinstance(1, int)
True
>>> isinstance(dog, Dog)
True
注意:因为Dog继承自Animal,所以:
>>> isinstance(dog, Animal)
True
获取对象信息:
type()一般用来判断基本类型:
>>> type(123)
<class 'int'>
>>> type('str')
<class 'str'>
>>> type(None)
<type(None) 'NoneType'>
如果一个变量指向函数或者类,也可以用type()
判断:
>>> type(abs)
<class 'builtin_function_or_method'>
>>> type(dog)
<class '__main__.Dog'>
判断两个值类型是否相同:
>>> type(123)==type(456)
True
>>> type(123)==int
True
>>> type('abc')==type('123')
True
>>> type('abc')==str
True
>>> type('abc')==type(123)
False
判断基本数据类型可以直接写int
,str
等,但如果要判断一个对象是否是函数怎么办?可以使用types
模块中定义的常量:
>>> import types
>>> def fn():
... pass
...
>>> type(fn)==types.FunctionType
True
>>> type(abs)==types.BuiltinFunctionType
True
>>> type(lambda x: x)==types.LambdaType
True
>>> type((x for x in range(10)))==types.GeneratorType
True
使用dir()
如果要获得一个对象的所有属性和方法,可以使用dir()
函数,它返回一个包含字符串的list,比如,获得一个str对象的所有属性和方法:
>>> dir('ABC')
['__add__', '__class__',..., '__subclasshook__', 'capitalize', 'casefold',..., 'zfill']
类似__xxx__
的属性和方法在Python中都是有特殊用途的,比如__len__
方法返回长度。在Python中,如果你调用len()
函数试图获取一个对象的长度,实际上,在len()
函数内部,它自动去调用该对象的__len__()
方法,我们自己写的类,如果也想用len(myObj)
的话,就自己写一个__len__()
方法:
>>> class MyDog(object):
... def __len__(self):
... return 100
...
>>> dog = MyDog()
>>> len(dog)
100
getattr()
、setattr()、
hasattr()
:
>>> class MyObject(object):
... def __init__(self):
... self.x = 9
... def power(self):
... return self.x * self.x
...
>>> obj = MyObject()
>>> hasattr(obj, 'x') # 有属性'x'吗?
True
>>> obj.x
9
>>> hasattr(obj, 'y') # 有属性'y'吗?
False
>>> setattr(obj, 'y', 19) # 设置一个属性'y'
>>> hasattr(obj, 'y') # 有属性'y'吗?
True
>>> getattr(obj, 'y') # 获取属性'y'
19
>>> obj.y # 获取属性'y'
19
通过内置的一系列函数,我们可以对任意一个Python对象进行剖析,拿到其内部的数据。要注意的是,只有在不知道对象信息的时候,我们才会去获取对象信息。如果可以直接写:sum = obj.x + obj.y,就不要写:sum = getattr(obj, 'x') + getattr(obj, 'y')