part2
1.成员
class Foo:
# 跟函数一样,如果不调用类,内部代码不执行
city = "nanjing"
def __init__(self,name):
self.name = name
def func(self):
pass
obj1 = Foo("a1")
obj2 = Foo("b2")
print(obj1.name)
print(obj2.name)
# 结果为:a1 b2
print(obj1.city)
print(obj2.city)
print(Foo.city)
# 结果都是nanjing
# 前两行只有python能实现,一般,第三行为规范写法(谁的成员去谁哪儿去取)
obj1、obj2在创建的时候其内部都会存在一个类对象指针指向Foo类
类变量(静态字段/属性)
比如city
-
定义:写在类的下一级和方法同一级
-
访问:
类.类变量名称 对象.类变量名称
class Foo: # 跟函数一样,如果不调用类,内部代码不执行 city = "nanjing" def __init__(self,name,city): self.name = name self.city = city obj1 = Foo("a1","beijing") obj2 = Foo("b2","shanghai") print(obj1.city) print(obj2.city) print(Foo.city) # 结果为:beijing shanghai nanjing
-
面试题
class Base: x = 1 obj = Base() print(obj.x) # 结果为1 obj.x = 123 # 在对象中(不是类中!)添加了一个x=123的变量 obj.y = 222 # 在对象中(不是类中!)添加了一个y=222的变量 print(obj.x) # 结果为123 print(obj.y) # 结果为222 Base.x = 6 print(Base.x) # 结果为6,相当于去类里修改类变量
class Father(object): # 等同于 class Father: x = 1 class Son1(Father): pass class Son2(Father): pass print(Father.x,Son1.x,Son2.x) # 1 1 1 Father.x = 10 print(Father.x,Son1.x,Son2.x) # 10 10 10 Son1.x = 1 print(Father.x,Son1.x,Son2.x) # 10 1 10 Son2.x = 2 print(Father.x,Son1.x,Son2.x) # 10 1 2 obj = Son1() print(obj.x) # 1 obj.x = 9 print(Son1.x) # 1
-
总结:找变量优先找自己的,自己没有找 类 或者 基类;修改或者赋值只能在自己内部设置。
方法(绑定方法/普通方法)
比如 init 、func
- 定义:至少有一个self参数
- 执行:必须通过实例化对象调用
class Foo:
def __init__(self):
self.name = 1
def func(self,a):
print(self.name,a)
obj = Foo()
obj.func(2)
静态方法
- 定义:@staticmethod装饰器;参数无限制
- 执行:类.静态方法名()(对象.静态方法名() 在python也可以,但不推荐使用)
class Foo:
@staticmethod
def func():
print(111)
Foo.func()
类方法
- 定义:@classmethod装饰器;至少有cls参数(表示当前类)
- 执行:类.类方法()(对象.类方法() 在python也可以,但不推荐使用)
class Foo:
@classmethod
def func2(cls,a,b):
print("cls为当前类",cls)
print(a,b)
Foo.func2(1,2)
obj = Foo()
obj.func2(1,2)
-
面试题
# 问题: @staticmethod 和 @classmethod ''' 一个是类方法一个是静态方法 定义: 类方法:用@classmethod做装饰器且至少有一个cls参数。 静态方法:用@staticmethod做装饰器且参数无限制。 调用 类.方法直接调用(对象.方法也可以调用但不推荐) '''
属性
- 定义:用@property装饰器;只有一个self参数
- 执行:对象.方法 不用加括号
class Foo:
@property
def func(self):
print(123)
return 666
obj = Foo()
result = obj.func
print(result)
# 属性的应用(用普通方法也可以实现)
class Page:
def __init__(self,total_count,current_page,per_page_count = 10):
self.total_count = total_count
self.current_page = current_page
self.per_page_count = per_page_count
@property
def start_index(self):
return (self.current_page - 1)*self.per_page_count
@property
def end_index(self):
return (self.current_page) * self.per_page_count
user_list = []
for i in range(321):
user_list.append(f"user{i}")
# 分页展示
current_page = int(input("请输入要查看的页码:"))
p = Page(321,current_page)
data_list = user_list[p.start_index:p.end_index]
for i in data_list:
print(i)
对象(实例)成员
实例变量(字段/属性)比如 name
class Foo:
# 跟函数一样,如果不调用类,内部代码不执行
city = "nanjing"
def __init__(self,name):
self.name = name
def func(self):
pass
obj1 = Foo("a1")
obj2 = Foo("b2")
print(obj1.name)
print(obj2.name)
# 结果为:a1 b2
2.成员修饰符
- 公有,所有地方都能访问到。
- 私有,只有自己可以访问到。
class Foo:
def __init__(self,name):
self.name = name # 此时的name为公有的
def func(self):
print(self.name)
obj = Foo("a1")
print(obj.name) # 结果为a1
obj.func() # 结果为a1
class Foo:
def __init__(self,name):
self.__name = name # 此时的name为私有的
def func(self):
print(self.__name)
obj = Foo("a1")
# print(obj.__name) # 此时执行会报错(外部无法访问)
obj.func() # 结果为a1(func()为内部方法可以调用)
class Foo:
__x = 1
@staticmethod
def func():
print(Foo.__x)
# print(Foo.__x) # 报错
Foo.func()
class Foo:
def __func(self):
print("func")
def show(self):
print("show")
self.__func()
obj = Foo()
# obj.__func() # 报错
obj.show()
总结:成员前面加 __ 变为私有(只有内部才能访问,子类都不能访问)
# 了解即可
class Foo;
def __init__(self,x):
self.__x = x
obj = Foo("a1")
print(obj._Foo__x) # 强制访问私有成员
3.补充
class Foo:
def __init__(self,name):
self.name = name
cls_list = []
for i in range(10):
cls_list.append(Foo)
for i in range(len(cls_list)):
obj = cls_list[i](i)
print(obj.name)
class Foo:
def __init__(self,name):
self.name = name
B = Foo
obj = B("a1")
print(obj.name)
class Foo:
def f1(self):
print("f1")
def f2(self):
print("f2")
obj = Foo()
l = [obj.f1,obj.f2]
for i in l:
i()
class Foo:
def f1(self):
print("f1")
def f2(self):
print("f2")
def f3(self):
l = [self.f1,self.f2]
for i in l:
i()
obj = Foo()
obj.f3()
class Foo:
def f1(self):
print("f1")
def f2(self):
print("f2")
def f3(self):
info = {"1":self.f1,"2":self.f2}
choice = input("请选择:")
method = info.get(choice)
method()
class Foo:
pass
class Foo(object):
pass
# 上述两种写法在python3中是一样的,因为所有的类默认继承object类(新式类)
# object类时帮助实例化时开辟内存的
Foo() # 默认执行object中的__init__方法
# python2中:
# 经典类:
class Foo:
pass
# 新式类:
class Foo(object):
pass
class school(object):
def _init__(self,title, addr):
self.title = title
self.address = addr
class classRoom(object):
def _init__(self,name, school_object):
self.name = name
self.school = school_object
s1 = School('北京','沙河')
s2 = Schoo1('上海','浦东')
s3 = School('深圳','南山')
c1 = ClassRoom("全栈21期",s1)
c1.name
c1.school.title
c1.school.address
面试:
-
面向对象?
从三大特性去说(面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。对象是封装了数据结构及可以施加在这些数据结构上的操作的封装体。)
-
类和对象是什么关系?
对象是类的一个实例
-
self是什么?
self本质上就是一个形式参数,对象调用方法时,python内部会将该对象传给这个参数。